From: "Sun, Zailiang" <zailiang.sun@intel.com>
To: "Kinney, Michael D" <michael.d.kinney@intel.com>,
"devel@edk2.groups.io" <devel@edk2.groups.io>
Cc: "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: Re: [edk2-platforms: Patch 6/8] Platform/Vlv2TbltDevicePkg: Import Vlv2TbltDevicePkg from edk2
Date: Mon, 13 May 2019 02:52:17 +0000 [thread overview]
Message-ID: <7CB7EF03E15B5D48981329A508747A9850C63AE3@SHSMSX104.ccr.corp.intel.com> (raw)
In-Reply-To: <20190510033435.24112-7-michael.d.kinney@intel.com>
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>aNII&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<&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^E|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$5CoJU0JG^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`iTUBt9i>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Å$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@�P@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=sVU&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--
> %?Gw70Ktd
> 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%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<fT{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	Lg&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|mvnG
> >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$TYmQqas$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*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}+WVhtJY;#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={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`99ovvc-
> 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�a8L+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<>~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{=TeUkW~&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#{`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
next prev parent reply other threads:[~2019-05-13 2:52 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
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 [this message]
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
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=7CB7EF03E15B5D48981329A508747A9850C63AE3@SHSMSX104.ccr.corp.intel.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox