summaryrefslogtreecommitdiffstats
path: root/QuarkPlatformPkg/Platform
diff options
context:
space:
mode:
authorMichael Kinney <michael.d.kinney@intel.com>2015-12-15 19:23:57 +0000
committermdkinney <mdkinney@Edk2>2015-12-15 19:23:57 +0000
commitb303605e1b7e113b4311daf161c6c3289350447b (patch)
tree67bf068eb99ea84822f234b7194ee1084ee5455a /QuarkPlatformPkg/Platform
parent9b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164 (diff)
downloadedk2-b303605e1b7e113b4311daf161c6c3289350447b.tar.gz
edk2-b303605e1b7e113b4311daf161c6c3289350447b.tar.bz2
edk2-b303605e1b7e113b4311daf161c6c3289350447b.zip
QuarkPlatformPkg: Add new package for Galileo boards
Changes for V4 ============== 1) Move delete of QuarkSocPkg\QuarkNorthCluster\Binary\QuarkMicrocode from QuarkPlatformPkg commit to QuarkSocPkg commit 2) Fix incorrect license header in PlatformSecLibModStrs.uni Changes for V3 ============== 1) Set PcdResetOnMemoryTypeInformationChange FALSE in QuarkMin.dsc This is required because QuarkMin.dsc uses the emulated variable driver that does not preserve any non-volatile UEFI variables across reset. If the condition is met where the memory type information variable needs to be updated, then the system will reset every time the UEFI Shell is run. By setting this PCD to FALSE, then reset action is disabled. 2) Move one binary file to QuarkSocBinPkg 3) Change RMU.bin FILE statements to INF statement in DSC FD region to be compatible with PACKAGES_PATH search for QuarkSocBinPkg Changes for V2 ============== 1) Use new generic PCI serial driver PciSioSerialDxe in MdeModulePkg 2) Configure PcdPciSerialParameters for PCI serial driver for Quark 3) Use new MtrrLib API to reduce time to set MTRRs for all DRAM 4) Convert all UNI files to utf-8 5) Replace tabs with spaces and remove trailing spaces 6) Add License.txt Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Michael Kinney <michael.d.kinney@intel.com> Acked-by: Jordan Justen <jordan.l.justen@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@19287 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'QuarkPlatformPkg/Platform')
-rw-r--r--QuarkPlatformPkg/Platform/Dxe/MemorySubClass/MemorySubClass.c441
-rw-r--r--QuarkPlatformPkg/Platform/Dxe/MemorySubClass/MemorySubClass.h71
-rw-r--r--QuarkPlatformPkg/Platform/Dxe/MemorySubClass/MemorySubClass.inf66
-rw-r--r--QuarkPlatformPkg/Platform/Dxe/MemorySubClass/MemorySubClassStrings.uni35
-rw-r--r--QuarkPlatformPkg/Platform/Dxe/PlatformInit/PlatformConfig.c449
-rw-r--r--QuarkPlatformPkg/Platform/Dxe/PlatformInit/PlatformInitDxe.c93
-rw-r--r--QuarkPlatformPkg/Platform/Dxe/PlatformInit/PlatformInitDxe.h64
-rw-r--r--QuarkPlatformPkg/Platform/Dxe/PlatformInit/PlatformInitDxe.inf62
-rw-r--r--QuarkPlatformPkg/Platform/Dxe/SaveMemoryConfig/SaveMemoryConfig.c124
-rw-r--r--QuarkPlatformPkg/Platform/Dxe/SaveMemoryConfig/SaveMemoryConfig.inf50
-rw-r--r--QuarkPlatformPkg/Platform/Dxe/Setup/CommonHeader.h61
-rw-r--r--QuarkPlatformPkg/Platform/Dxe/Setup/DxePlatform.inf82
-rw-r--r--QuarkPlatformPkg/Platform/Dxe/Setup/KeyboardLayout.c268
-rw-r--r--QuarkPlatformPkg/Platform/Dxe/Setup/QNCRegTable.c86
-rw-r--r--QuarkPlatformPkg/Platform/Dxe/Setup/SetupPlatform.c103
-rw-r--r--QuarkPlatformPkg/Platform/Dxe/Setup/SetupPlatform.h77
-rw-r--r--QuarkPlatformPkg/Platform/Dxe/Setup/Strings.uni53
-rw-r--r--QuarkPlatformPkg/Platform/Dxe/Setup/processor.c46
-rw-r--r--QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/CommonHeader.h40
-rw-r--r--QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBaseBoardManufacturer.uni25
-rw-r--r--QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBaseBoardManufacturerData.c51
-rw-r--r--QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBaseBoardManufacturerFunction.c187
-rw-r--r--QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBiosVendor.uni24
-rw-r--r--QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBiosVendorData.c98
-rw-r--r--QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBiosVendorFunction.c228
-rw-r--r--QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBootInformationData.c30
-rw-r--r--QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBootInformationFunction.c77
-rw-r--r--QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscChassisManufacturer.uni23
-rw-r--r--QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscChassisManufacturerData.c42
-rw-r--r--QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscChassisManufacturerFunction.c174
-rw-r--r--QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscDevicePath.h48
-rw-r--r--QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscNumberOfInstallableLanguagesData.c34
-rw-r--r--QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscNumberOfInstallableLanguagesFunction.c248
-rw-r--r--QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOemString.uni18
-rw-r--r--QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOemStringData.c26
-rw-r--r--QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOemStringFunction.c87
-rw-r--r--QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOnboardDevice.uni24
-rw-r--r--QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOnboardDeviceData.c55
-rw-r--r--QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOnboardDeviceFunction.c111
-rw-r--r--QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscPortInternalConnectorDesignator.uni59
-rw-r--r--QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscPortInternalConnectorDesignatorData.c190
-rw-r--r--QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscPortInternalConnectorDesignatorFunction.c298
-rw-r--r--QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemManufacturer.uni26
-rw-r--r--QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemManufacturerData.c38
-rw-r--r--QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemManufacturerFunction.c204
-rw-r--r--QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemOptionString.uni20
-rw-r--r--QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemOptionStringData.c29
-rw-r--r--QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemOptionStringFunction.c90
-rw-r--r--QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemSlotDesignation.uni33
-rw-r--r--QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemSlotDesignationData.c363
-rw-r--r--QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemSlotDesignationFunction.c291
-rw-r--r--QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemSlotOnboardDevices.uni29
-rw-r--r--QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMisc.h143
-rw-r--r--QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMiscDataTable.c115
-rw-r--r--QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMiscDxe.inf314
-rw-r--r--QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMiscEntryPoint.c88
-rw-r--r--QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMiscStrings.uni32
-rw-r--r--QuarkPlatformPkg/Platform/Pei/PlatformConfig/PlatformConfigPei.c87
-rw-r--r--QuarkPlatformPkg/Platform/Pei/PlatformConfig/PlatformConfigPei.inf51
-rw-r--r--QuarkPlatformPkg/Platform/Pei/PlatformInit/BootMode.c257
-rw-r--r--QuarkPlatformPkg/Platform/Pei/PlatformInit/CommonHeader.h84
-rw-r--r--QuarkPlatformPkg/Platform/Pei/PlatformInit/Generic/Recovery.c501
-rw-r--r--QuarkPlatformPkg/Platform/Pei/PlatformInit/MemoryCallback.c237
-rw-r--r--QuarkPlatformPkg/Platform/Pei/PlatformInit/MrcWrapper.c1641
-rw-r--r--QuarkPlatformPkg/Platform/Pei/PlatformInit/MrcWrapper.h240
-rw-r--r--QuarkPlatformPkg/Platform/Pei/PlatformInit/PeiFvSecurity.c117
-rw-r--r--QuarkPlatformPkg/Platform/Pei/PlatformInit/PeiFvSecurity.h73
-rw-r--r--QuarkPlatformPkg/Platform/Pei/PlatformInit/PlatformEarlyInit.c962
-rw-r--r--QuarkPlatformPkg/Platform/Pei/PlatformInit/PlatformEarlyInit.h307
-rw-r--r--QuarkPlatformPkg/Platform/Pei/PlatformInit/PlatformEarlyInit.inf200
-rw-r--r--QuarkPlatformPkg/Platform/Pei/PlatformInit/PlatformErratas.c184
-rw-r--r--QuarkPlatformPkg/Platform/SpiFvbServices/FvbInfo.c338
-rw-r--r--QuarkPlatformPkg/Platform/SpiFvbServices/FwBlockService.c2066
-rw-r--r--QuarkPlatformPkg/Platform/SpiFvbServices/FwBlockService.h314
-rw-r--r--QuarkPlatformPkg/Platform/SpiFvbServices/PlatformSmmSpi.c37
-rw-r--r--QuarkPlatformPkg/Platform/SpiFvbServices/PlatformSmmSpi.inf86
-rw-r--r--QuarkPlatformPkg/Platform/SpiFvbServices/PlatformSpi.inf85
-rw-r--r--QuarkPlatformPkg/Platform/SpiFvbServices/SpiFlashDevice.c337
-rw-r--r--QuarkPlatformPkg/Platform/SpiFvbServices/SpiFlashDevice.h187
79 files changed, 14634 insertions, 0 deletions
diff --git a/QuarkPlatformPkg/Platform/Dxe/MemorySubClass/MemorySubClass.c b/QuarkPlatformPkg/Platform/Dxe/MemorySubClass/MemorySubClass.c
new file mode 100644
index 0000000000..4cd73ae153
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Dxe/MemorySubClass/MemorySubClass.c
@@ -0,0 +1,441 @@
+/** @file
+This is the driver that locates the MemoryConfigurationData Variable, if it
+exists, and reports the data to the DataHub.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "MemorySubClass.h"
+
+extern UINT8 MemorySubClassStrings[];
+
+EFI_GUID gEfiMemorySubClassDriverGuid = EFI_MEMORY_SUBCLASS_DRIVER_GUID;
+
+EFI_STATUS
+MemorySubClassEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+/*++
+
+ Routine Description:
+ This is the standard EFI driver point that detects whether there is a
+ MemoryConfigurationData Variable and, if so, reports memory configuration info
+ to the DataHub.
+
+ Arguments:
+ ImageHandle - Handle for the image of this driver
+ SystemTable - Pointer to the EFI System Table
+
+ Returns:
+ EFI_SUCCESS if the data is successfully reported
+ EFI_NOT_FOUND if the HOB list could not be located.
+
+--*/
+{
+// UINT8 Index;
+ UINTN DataSize;
+ UINT8 Dimm;
+ UINTN StringBufferSize;
+ UINT8 NumSlots;
+ UINTN DevLocStrLen;
+ UINTN BankLocStrLen;
+ UINTN ManuStrLen;
+ UINTN SerialNumStrLen;
+ UINTN AssertTagStrLen;
+ UINTN PartNumStrLen;
+ UINTN MemoryDeviceSize;
+ CHAR8* OptionalStrStart;
+ UINT16 ArrayInstance;
+ UINT64 DimmMemorySize;
+ UINT64 TotalMemorySize;
+ UINT32 Data;
+ UINT32 MemoryCapacity;
+ BOOLEAN MemoryDeviceSizeUnitMega;
+ EFI_STATUS Status;
+ EFI_STRING StringBuffer;
+ EFI_STRING DevLocStr;
+ EFI_STRING BankLocStr;
+ EFI_STRING ManuStr;
+ EFI_STRING SerialNumStr;
+ EFI_STRING AssertTagStr;
+ EFI_STRING PartNumStr;
+ EFI_HII_HANDLE HiiHandle;
+ EFI_SMBIOS_HANDLE MemArraySmbiosHandle;
+ EFI_SMBIOS_HANDLE MemArrayMappedAddrSmbiosHandle;
+ EFI_SMBIOS_HANDLE MemDevSmbiosHandle;
+ EFI_SMBIOS_HANDLE MemDevMappedAddrSmbiosHandle;
+ EFI_SMBIOS_HANDLE MemModuleInfoSmbiosHandle;
+ SMBIOS_TABLE_TYPE6 *Type6Record;
+ SMBIOS_TABLE_TYPE16 *Type16Record;
+ SMBIOS_TABLE_TYPE17 *Type17Record;
+ SMBIOS_TABLE_TYPE19 *Type19Record;
+ SMBIOS_TABLE_TYPE20 *Type20Record;
+ EFI_SMBIOS_PROTOCOL *Smbios;
+ EFI_MEMORY_ARRAY_LINK_DATA ArrayLink;
+ EFI_MEMORY_ARRAY_LOCATION_DATA ArrayLocationData;
+ EFI_MEMORY_DEVICE_START_ADDRESS_DATA DeviceStartAddress;
+
+
+ DataSize = 0;
+ Dimm = 0;
+
+
+ //
+ // Allocate Buffers
+ //
+ StringBufferSize = (sizeof (CHAR16)) * 100;
+ StringBuffer = AllocateZeroPool (StringBufferSize);
+ ASSERT (StringBuffer != NULL);
+
+ //
+ // Locate dependent protocols
+ //
+ Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID**)&Smbios);
+ ASSERT_EFI_ERROR (Status);
+
+
+ //
+ // Add our default strings to the HII database. They will be modified later.
+ //
+ HiiHandle = HiiAddPackages (
+ &gEfiMemorySubClassDriverGuid,
+ NULL,
+ MemorySubClassStrings,
+ NULL
+ );
+ ASSERT (HiiHandle != NULL);
+
+ //
+ // Create physical array and associated data for all mainboard memory
+ // This will translate into a Type 16 SMBIOS Record
+ //
+ ArrayInstance = 1;
+
+ McD0PciCfg32 (QNC_ACCESS_PORT_MCR) = MESSAGE_READ_DW (0x3, 0x8);
+ TotalMemorySize = McD0PciCfg32 (QNC_ACCESS_PORT_MDR);
+
+ ArrayLocationData.MemoryArrayLocation = EfiMemoryArrayLocationSystemBoard;
+ ArrayLocationData.MemoryArrayUse = EfiMemoryArrayUseSystemMemory;
+
+ ArrayLocationData.MemoryErrorCorrection = EfiMemoryErrorCorrectionNone;
+
+ Data = 0x40000000;//(UINT32) RShiftU64(MemConfigData->RowInfo.MaxMemory, 10);
+
+ ArrayLocationData.MaximumMemoryCapacity.Exponent = (UINT16) LowBitSet32 (Data);
+ ArrayLocationData.MaximumMemoryCapacity.Value = (UINT16) (Data >> ArrayLocationData.MaximumMemoryCapacity.Exponent);
+
+ NumSlots = 2;// (UINT8)(MemConfigData->RowInfo.MaxRows >> 1);
+ ArrayLocationData.NumberMemoryDevices = (UINT16)(NumSlots);
+
+ //
+ // Report top level physical array to Type 16 SMBIOS Record
+ //
+ Type16Record = AllocatePool(sizeof(SMBIOS_TABLE_TYPE16) + 1 + 1);
+ ZeroMem(Type16Record, sizeof(SMBIOS_TABLE_TYPE16) + 1 + 1);
+
+ Type16Record->Hdr.Type = EFI_SMBIOS_TYPE_PHYSICAL_MEMORY_ARRAY;
+ Type16Record->Hdr.Length = sizeof(SMBIOS_TABLE_TYPE16);
+ Type16Record->Hdr.Handle = 0;
+
+ Type16Record->Location = (UINT8)ArrayLocationData.MemoryArrayLocation;
+
+ Type16Record->Use = (UINT8)ArrayLocationData.MemoryArrayUse;
+
+ Type16Record->MemoryErrorCorrection = (UINT8)ArrayLocationData.MemoryErrorCorrection;
+
+ MemoryCapacity = (UINT32) ArrayLocationData.MaximumMemoryCapacity.Value * (1 << ((UINT32) ArrayLocationData.MaximumMemoryCapacity.Exponent - 10));
+ Type16Record->MaximumCapacity = MemoryCapacity;
+
+ Type16Record->MemoryErrorInformationHandle = 0xfffe;
+
+ Type16Record->NumberOfMemoryDevices = ArrayLocationData.NumberMemoryDevices;
+ //
+ // Don't change it. This handle will be referenced by type 17 records
+ //
+ MemArraySmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+ Status = Smbios->Add (Smbios, NULL, &MemArraySmbiosHandle, (EFI_SMBIOS_TABLE_HEADER*) Type16Record);
+ FreePool(Type16Record);
+ ASSERT_EFI_ERROR (Status);
+
+ // Do associated data for each DIMM
+ //RowConfArray = &MemConfigData->RowConfArray;
+
+ //
+ // Get total memory size for the construction of smbios record type 19
+ //
+ //TotalMemorySize = 0;// MSG_BUS_READ(0x0208);
+
+ //
+ // Generate Memory Array Mapped Address info
+ //
+ Type19Record = AllocatePool(sizeof (SMBIOS_TABLE_TYPE19));
+ ZeroMem(Type19Record, sizeof(SMBIOS_TABLE_TYPE19));
+ Type19Record->Hdr.Type = EFI_SMBIOS_TYPE_MEMORY_ARRAY_MAPPED_ADDRESS;
+ Type19Record->Hdr.Length = sizeof(SMBIOS_TABLE_TYPE19);
+ Type19Record->Hdr.Handle = 0;
+ Type19Record->StartingAddress = 0;
+ Type19Record->EndingAddress = (UINT32)RShiftU64(TotalMemorySize, 10) - 1;
+ Type19Record->MemoryArrayHandle = MemArraySmbiosHandle;
+ Type19Record->PartitionWidth = (UINT8)(NumSlots);
+
+ //
+ // Generate Memory Array Mapped Address info (TYPE 19)
+ //
+ MemArrayMappedAddrSmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+ Status = Smbios->Add (Smbios, NULL, &MemArrayMappedAddrSmbiosHandle, (EFI_SMBIOS_TABLE_HEADER*) Type19Record);
+ FreePool(Type19Record);
+ ASSERT_EFI_ERROR (Status);
+
+
+ // Use SPD data to generate Device Type info
+ ZeroMem (&ArrayLink, sizeof (EFI_MEMORY_ARRAY_LINK_DATA));
+ ArrayLink.MemoryDeviceLocator = STRING_TOKEN(STR_MEMORY_SUBCLASS_DEVICE_LOCATOR_0);
+ ArrayLink.MemoryBankLocator = STRING_TOKEN(STR_MEMORY_SUBCLASS_DEVICE_LOCATOR_0);
+ ArrayLink.MemoryAssetTag = STRING_TOKEN(STR_MEMORY_SUBCLASS_UNKNOWN);
+ ArrayLink.MemoryArrayLink.ProducerName = gEfiMemorySubClassDriverGuid;
+ ArrayLink.MemoryArrayLink.Instance = ArrayInstance;
+ ArrayLink.MemoryArrayLink.SubInstance = EFI_SUBCLASS_INSTANCE_NON_APPLICABLE;
+ ArrayLink.MemorySubArrayLink.ProducerName = gEfiMemorySubClassDriverGuid;
+ ArrayLink.MemorySubArrayLink.SubInstance = EFI_SUBCLASS_INSTANCE_NON_APPLICABLE;
+ ArrayLink.MemoryFormFactor = EfiMemoryFormFactorChip;
+ ArrayLink.MemoryType = EfiMemoryTypeDdr2;
+
+
+ StrCpy (StringBuffer, L"NO DIMM,MEMROY DOWN");
+ ArrayLink.MemoryManufacturer = HiiSetString (
+ HiiHandle,
+ 0,
+ StringBuffer,
+ NULL
+ );
+ ArrayLink.MemorySerialNumber = HiiSetString (
+ HiiHandle,
+ 0,
+ StringBuffer,
+ NULL
+ );
+
+ ArrayLink.MemoryPartNumber = HiiSetString (
+ HiiHandle,
+ 0,
+ StringBuffer,
+ NULL
+ );
+
+ //
+ // Hardcode value. Need to revise for different configuration.
+ //
+ ArrayLink.MemoryTotalWidth = 64;
+ ArrayLink.MemoryDataWidth = 64;
+
+ DimmMemorySize = TotalMemorySize;// MSG_BUS_READ(0x0208);
+
+ ArrayLink.MemoryDeviceSize.Exponent = (UINT16) LowBitSet64 (DimmMemorySize);
+ ArrayLink.MemoryDeviceSize.Value = (UINT16) RShiftU64(DimmMemorySize, ArrayLink.MemoryDeviceSize.Exponent);
+ ArrayLink.MemoryTypeDetail.Synchronous = 1;
+ Data = 800;
+ ArrayLink.MemorySpeed = *((EFI_EXP_BASE10_DATA *) &Data);
+
+
+
+ DevLocStr = HiiGetPackageString(&gEfiMemorySubClassDriverGuid, ArrayLink.MemoryDeviceLocator, NULL);
+ DevLocStrLen = StrLen(DevLocStr);
+ ASSERT(DevLocStrLen <= SMBIOS_STRING_MAX_LENGTH);
+
+ BankLocStr = HiiGetPackageString(&gEfiMemorySubClassDriverGuid, ArrayLink.MemoryBankLocator, NULL);
+ BankLocStrLen = StrLen(BankLocStr);
+ ASSERT(BankLocStrLen <= SMBIOS_STRING_MAX_LENGTH);
+
+ ManuStr = HiiGetPackageString(&gEfiMemorySubClassDriverGuid, ArrayLink.MemoryManufacturer, NULL);
+ ManuStrLen = StrLen(ManuStr);
+ ASSERT(ManuStrLen <= SMBIOS_STRING_MAX_LENGTH);
+
+ SerialNumStr = HiiGetPackageString(&gEfiMemorySubClassDriverGuid, ArrayLink.MemorySerialNumber, NULL);
+ SerialNumStrLen = StrLen(SerialNumStr);
+ ASSERT(SerialNumStrLen <= SMBIOS_STRING_MAX_LENGTH);
+
+ AssertTagStr = HiiGetPackageString(&gEfiMemorySubClassDriverGuid, ArrayLink.MemoryAssetTag, NULL);
+ AssertTagStrLen = StrLen(AssertTagStr);
+ ASSERT(AssertTagStrLen <= SMBIOS_STRING_MAX_LENGTH);
+
+ PartNumStr = HiiGetPackageString(&gEfiMemorySubClassDriverGuid, ArrayLink.MemoryPartNumber, NULL);
+ PartNumStrLen = StrLen(PartNumStr);
+ ASSERT(PartNumStrLen <= SMBIOS_STRING_MAX_LENGTH);
+
+ //
+ // Report DIMM level memory module information to smbios (Type 6)
+ //
+ DataSize = sizeof(SMBIOS_TABLE_TYPE6) + DevLocStrLen + 1 + 1;
+ Type6Record = AllocatePool(DataSize);
+ ZeroMem(Type6Record, DataSize);
+ Type6Record->Hdr.Type = EFI_SMBIOS_TYPE_MEMORY_MODULE_INFORMATON;
+ Type6Record->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE6);
+ Type6Record->Hdr.Handle = 0;
+ Type6Record->SocketDesignation = 1;
+ if (ArrayLink.MemorySpeed.Value == 0) {
+ Type6Record->CurrentSpeed = 0;
+ } else {
+ //
+ // Memory speed is in ns unit
+ //
+ Type6Record->CurrentSpeed = (UINT8)(1000 / (ArrayLink.MemorySpeed.Value));
+ }
+ //
+ // Device Size
+ //
+ MemoryDeviceSize = (UINTN)(ArrayLink.MemoryDeviceSize.Value) * (UINTN)(1 << ArrayLink.MemoryDeviceSize.Exponent);
+ if (MemoryDeviceSize == 0) {
+ *(UINT8*)&(Type6Record->InstalledSize) = 0x7F;
+ *(UINT8*)&(Type6Record->EnabledSize) = 0x7F;
+ } else {
+ MemoryDeviceSize = (UINTN) RShiftU64 ((UINT64) MemoryDeviceSize, 21);
+ while (MemoryDeviceSize != 0) {
+ (*(UINT8*)&(Type6Record->InstalledSize))++;
+ (*(UINT8*)&(Type6Record->EnabledSize))++;
+ MemoryDeviceSize = (UINTN) RShiftU64 ((UINT64) MemoryDeviceSize,1);
+ }
+ }
+
+ if (ArrayLink.MemoryFormFactor == EfiMemoryFormFactorDimm ||
+ ArrayLink.MemoryFormFactor == EfiMemoryFormFactorFbDimm) {
+ *(UINT16*)&Type6Record->CurrentMemoryType |= 1<<8;
+ }
+ if (ArrayLink.MemoryFormFactor == EfiMemoryFormFactorSimm) {
+ *(UINT16*)&Type6Record->CurrentMemoryType |= 1<<7;
+ }
+ if (ArrayLink.MemoryType == EfiMemoryTypeSdram) {
+ *(UINT16*)&Type6Record->CurrentMemoryType |= 1<<10;
+ }
+ if (ArrayLink.MemoryTypeDetail.Edo == 1) {
+ *(UINT16*)&Type6Record->CurrentMemoryType |= 1<<4;
+ }
+ if (ArrayLink.MemoryTypeDetail.FastPaged == 1) {
+ *(UINT16*)&Type6Record->CurrentMemoryType |= 1<<3;
+ }
+ OptionalStrStart = (CHAR8 *)(Type6Record + 1);
+ UnicodeStrToAsciiStr(DevLocStr, OptionalStrStart);
+ MemModuleInfoSmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+ Status = Smbios->Add (Smbios, NULL, &MemModuleInfoSmbiosHandle, (EFI_SMBIOS_TABLE_HEADER*) Type6Record);
+ FreePool(Type6Record);
+ ASSERT_EFI_ERROR (Status);
+ //
+ // Report DIMM level Device Type to smbios (Type 17)
+ //
+ DataSize = sizeof (SMBIOS_TABLE_TYPE17) + DevLocStrLen + 1 + BankLocStrLen + 1 + ManuStrLen + 1 + SerialNumStrLen + 1 + AssertTagStrLen + 1 + PartNumStrLen + 1 + 1;
+ Type17Record = AllocatePool(DataSize);
+ ZeroMem(Type17Record, DataSize);
+ Type17Record->Hdr.Type = EFI_SMBIOS_TYPE_MEMORY_DEVICE;
+ Type17Record->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE17);
+ Type17Record->Hdr.Handle = 0;
+
+ Type17Record->MemoryArrayHandle = MemArraySmbiosHandle;
+ Type17Record->MemoryErrorInformationHandle = 0xfffe;
+ Type17Record->TotalWidth = ArrayLink.MemoryTotalWidth;
+ Type17Record->DataWidth = ArrayLink.MemoryDataWidth;
+ //
+ // Device Size
+ //
+ MemoryDeviceSize = ((UINTN) ArrayLink.MemoryDeviceSize.Value) << (ArrayLink.MemoryDeviceSize.Exponent - 10);
+ MemoryDeviceSizeUnitMega = FALSE;
+ //
+ // kilo as unit
+ //
+ if (MemoryDeviceSize > 0xffff) {
+ MemoryDeviceSize = MemoryDeviceSize >> 10;
+ //
+ // Mega as unit
+ //
+ MemoryDeviceSizeUnitMega = TRUE;
+ }
+
+ MemoryDeviceSize = MemoryDeviceSize & 0x7fff;
+ if (MemoryDeviceSize != 0 && MemoryDeviceSizeUnitMega == FALSE) {
+ MemoryDeviceSize |= 0x8000;
+ }
+ Type17Record->Size = (UINT16)MemoryDeviceSize;
+
+ Type17Record->FormFactor = (UINT8)ArrayLink.MemoryFormFactor;
+ Type17Record->DeviceLocator = 1;
+ Type17Record->BankLocator = 2;
+ Type17Record->MemoryType = (UINT8)ArrayLink.MemoryType;
+ CopyMem (
+ (UINT8 *) &Type17Record->TypeDetail,
+ &ArrayLink.MemoryTypeDetail,
+ 2
+ );
+
+ Type17Record->Speed = ArrayLink.MemorySpeed.Value;
+ Type17Record->Manufacturer = 3;
+ Type17Record->SerialNumber = 4;
+ Type17Record->AssetTag = 5;
+ Type17Record->PartNumber = 6;
+ //
+ // temporary solution for save device label information.
+ //
+ Type17Record->Attributes = (UINT8)(Dimm + 1);
+
+ OptionalStrStart = (CHAR8 *)(Type17Record + 1);
+ UnicodeStrToAsciiStr(DevLocStr, OptionalStrStart);
+ UnicodeStrToAsciiStr(BankLocStr, OptionalStrStart + DevLocStrLen + 1);
+ UnicodeStrToAsciiStr(ManuStr, OptionalStrStart + DevLocStrLen + 1 + BankLocStrLen + 1);
+ UnicodeStrToAsciiStr(SerialNumStr, OptionalStrStart + DevLocStrLen + 1 + BankLocStrLen + 1 + ManuStrLen + 1);
+ UnicodeStrToAsciiStr(AssertTagStr, OptionalStrStart + DevLocStrLen + 1 + BankLocStrLen + 1 + ManuStrLen + 1 + SerialNumStrLen + 1);
+ UnicodeStrToAsciiStr(PartNumStr, OptionalStrStart + DevLocStrLen + 1 + BankLocStrLen + 1 + ManuStrLen + 1 + SerialNumStrLen + 1 + AssertTagStrLen + 1);
+ MemDevSmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+ Status = Smbios->Add (Smbios, NULL, &MemDevSmbiosHandle, (EFI_SMBIOS_TABLE_HEADER*) Type17Record);
+ FreePool(Type17Record);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Generate Memory Device Mapped Address info
+ //
+ ZeroMem(&DeviceStartAddress, sizeof(EFI_MEMORY_DEVICE_START_ADDRESS_DATA));
+ DeviceStartAddress.MemoryDeviceStartAddress = 0;
+ DeviceStartAddress.MemoryDeviceEndAddress = DeviceStartAddress.MemoryDeviceStartAddress + DimmMemorySize-1;
+ DeviceStartAddress.PhysicalMemoryDeviceLink.ProducerName = gEfiMemorySubClassDriverGuid;
+ DeviceStartAddress.PhysicalMemoryDeviceLink.Instance = ArrayInstance;
+ DeviceStartAddress.PhysicalMemoryDeviceLink.SubInstance = (UINT16)(Dimm + 1);
+ DeviceStartAddress.PhysicalMemoryArrayLink.ProducerName = gEfiMemorySubClassDriverGuid;
+ DeviceStartAddress.PhysicalMemoryArrayLink.Instance = ArrayInstance;
+ DeviceStartAddress.PhysicalMemoryArrayLink.SubInstance = EFI_SUBCLASS_INSTANCE_NON_APPLICABLE;
+
+ //
+ // Single channel mode
+ //
+ DeviceStartAddress.MemoryDevicePartitionRowPosition = 0x01;
+ DeviceStartAddress.MemoryDeviceInterleavePosition = 0x00;
+ DeviceStartAddress.MemoryDeviceInterleaveDataDepth = 0x00;
+
+ //
+ // Generate Memory Device Mapped Address info (TYPE 20)
+ //
+ Type20Record = AllocatePool(sizeof (SMBIOS_TABLE_TYPE20));
+ ZeroMem(Type20Record, sizeof (SMBIOS_TABLE_TYPE20));
+ Type20Record->Hdr.Type = EFI_SMBIOS_TYPE_MEMORY_DEVICE_MAPPED_ADDRESS;
+ Type20Record->Hdr.Length = sizeof(SMBIOS_TABLE_TYPE20);
+ Type20Record->Hdr.Handle = 0;
+
+ Type20Record->StartingAddress = (UINT32)RShiftU64 (DeviceStartAddress.MemoryDeviceStartAddress, 10);
+ Type20Record->EndingAddress = (UINT32)RShiftU64 (DeviceStartAddress.MemoryDeviceEndAddress, 10);
+ Type20Record->MemoryDeviceHandle = MemDevSmbiosHandle;
+ Type20Record->MemoryArrayMappedAddressHandle = MemArrayMappedAddrSmbiosHandle;
+ Type20Record->PartitionRowPosition = DeviceStartAddress.MemoryDevicePartitionRowPosition;
+ Type20Record->InterleavePosition = DeviceStartAddress.MemoryDeviceInterleavePosition;
+ Type20Record->InterleavedDataDepth = DeviceStartAddress.MemoryDeviceInterleaveDataDepth;
+ MemDevMappedAddrSmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+ Status = Smbios->Add (Smbios, NULL, &MemDevMappedAddrSmbiosHandle, (EFI_SMBIOS_TABLE_HEADER*) Type20Record);
+ FreePool(Type20Record);
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
diff --git a/QuarkPlatformPkg/Platform/Dxe/MemorySubClass/MemorySubClass.h b/QuarkPlatformPkg/Platform/Dxe/MemorySubClass/MemorySubClass.h
new file mode 100644
index 0000000000..f0848143ce
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Dxe/MemorySubClass/MemorySubClass.h
@@ -0,0 +1,71 @@
+/** @file
+Header file for MemorySubClass Driver.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _MEMORY_SUB_CLASS_H
+#define _MEMORY_SUB_CLASS_H
+
+//
+// The package level header files this module uses
+//
+#include <FrameworkDxe.h>
+//
+// The protocols, PPI and GUID definitions for this module
+//
+#include <IndustryStandard/SmBios.h>
+#include <Protocol/Smbios.h>
+#include <Protocol/PciRootBridgeIo.h>
+#include <Protocol/SmbusHc.h>
+#include <Guid/DataHubRecords.h>
+#include <Guid/MemoryConfigData.h>
+#include <Protocol/HiiDatabase.h>
+#include <Guid/MdeModuleHii.h>
+
+//
+// The Library classes this module consumes
+//
+#include <Library/BaseLib.h>
+#include <Library/HobLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PrintLib.h>
+#include <Library/HiiLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PciLib.h>
+#include <Library/QNCAccessLib.h>
+
+#include "QNCAccess.h"
+
+
+
+//
+// This is the generated header file which includes whatever needs to be exported (strings + IFR)
+//
+
+#define EFI_MEMORY_SUBCLASS_DRIVER_GUID \
+ { 0xef17cee7, 0x267d, 0x4bfd, { 0xa2, 0x57, 0x4a, 0x6a, 0xb3, 0xee, 0x85, 0x91 }}
+
+//
+// Prototypes
+//
+EFI_STATUS
+MemorySubClassEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+#endif
diff --git a/QuarkPlatformPkg/Platform/Dxe/MemorySubClass/MemorySubClass.inf b/QuarkPlatformPkg/Platform/Dxe/MemorySubClass/MemorySubClass.inf
new file mode 100644
index 0000000000..415a3911e4
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Dxe/MemorySubClass/MemorySubClass.inf
@@ -0,0 +1,66 @@
+## @file
+# Component description file for MemorySubClass module.
+#
+# This is the driver that locates the MemoryConfigurationData Variable, if it
+# exists, and reports the data to the DataHub.
+# Copyright (c) 2013-2015 Intel Corporation.
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = MemorySubClass
+ FILE_GUID = EF17CEE7-267D-4BFD-A257-4A6AB3EE8591
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = MemorySubClassEntryPoint
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[Sources]
+ MemorySubClass.c
+ MemorySubClass.h
+ MemorySubClassStrings.uni
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ IntelFrameworkPkg/IntelFrameworkPkg.dec
+ QuarkSocPkg/QuarkSocPkg.dec
+ QuarkPlatformPkg/QuarkPlatformPkg.dec
+
+[LibraryClasses]
+ MemoryAllocationLib
+ HiiLib
+ PrintLib
+ BaseMemoryLib
+ DebugLib
+ UefiRuntimeServicesTableLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+ BaseLib
+ HobLib
+ PciLib
+ QNCAccessLib
+
+[Guids]
+ gEfiMemoryConfigDataGuid # ALWAYS_CONSUMED
+
+[Protocols]
+ gEfiSmbiosProtocolGuid # PROTOCOL ALWAYS_CONSUMED
+ gEfiSmbusHcProtocolGuid # PROTOCOL ALWAYS_CONSUMED
+
+[Depex]
+ gEfiVariableArchProtocolGuid AND gEfiVariableWriteArchProtocolGuid AND gEfiSmbiosProtocolGuid AND gEfiSmbusHcProtocolGuid
diff --git a/QuarkPlatformPkg/Platform/Dxe/MemorySubClass/MemorySubClassStrings.uni b/QuarkPlatformPkg/Platform/Dxe/MemorySubClass/MemorySubClassStrings.uni
new file mode 100644
index 0000000000..37f2697e47
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Dxe/MemorySubClass/MemorySubClassStrings.uni
@@ -0,0 +1,35 @@
+// /** @file
+// String definitions for Smbios Memory SubClass data.
+//
+// Copyright (c) 2013-2015 Intel Corporation.
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+//
+// **/
+
+
+/=#
+
+#langdef en-US "English"
+
+//
+// Begin English Language Strings
+//
+#string STR_MEMORY_SUBCLASS_UNKNOWN #language en-US "Unknown"
+#string STR_MEMORY_SUBCLASS_DEVICE_LOCATOR_0 #language en-US "SOLDER DOWN"
+#string STR_MEMORY_SUBCLASS_MANUFACTURER #language en-US "Manufacturer: "
+#string STR_MEMORY_SUBCLASS_SERIAL_NUMBER #language en-US "Serial Number: "
+#string STR_MEMORY_SUBCLASS_ASSET_TAG #language en-US "Asset Tag: "
+#string STR_MEMORY_SUBCLASS_PART_NUMBER #language en-US "PartNumber: "
+//
+// End English Language Strings
+//
+
+
diff --git a/QuarkPlatformPkg/Platform/Dxe/PlatformInit/PlatformConfig.c b/QuarkPlatformPkg/Platform/Dxe/PlatformInit/PlatformConfig.c
new file mode 100644
index 0000000000..38e5684c1f
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Dxe/PlatformInit/PlatformConfig.c
@@ -0,0 +1,449 @@
+/** @file
+Essential platform configuration.
+
+Copyright (c) 2013 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+
+**/
+
+#include "PlatformInitDxe.h"
+
+//
+// The protocols, PPI and GUID defintions for this module
+//
+
+//
+// The Library classes this module consumes
+//
+
+//
+// RTC:28208 - System hang/crash when entering probe mode(ITP) when relocating SMBASE
+// Workaround to make default SMRAM UnCachable
+//
+#define SMM_DEFAULT_SMBASE 0x30000 // Default SMBASE address
+#define SMM_DEFAULT_SMBASE_SIZE_BYTES 0x10000 // Size in bytes of default SMRAM
+
+BOOLEAN mMemCfgDone = FALSE;
+UINT8 ChipsetDefaultMac [6] = {0xff,0xff,0xff,0xff,0xff,0xff};
+
+VOID
+EFIAPI
+PlatformInitializeUart0MuxGalileo (
+ VOID
+ )
+/*++
+
+
+Routine Description:
+
+ This is the routine to initialize UART0 for DBG2 support. The hardware used in this process is a
+ Legacy Bridge (Legacy GPIO), I2C controller, a bi-directional MUX and a Cypress CY8C9540A chip.
+
+Arguments:
+
+ None.
+
+Returns:
+
+ None.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_I2C_DEVICE_ADDRESS I2CSlaveAddress;
+ UINTN Length;
+ UINT8 Buffer[2];
+
+ if (PlatformLegacyGpioGetLevel (R_QNC_GPIO_RGLVL_RESUME_WELL, GALILEO_DETERMINE_IOEXP_SLA_RESUMEWELL_GPIO)) {
+ I2CSlaveAddress.I2CDeviceAddress = GALILEO_IOEXP_J2HI_7BIT_SLAVE_ADDR;
+ } else {
+ I2CSlaveAddress.I2CDeviceAddress = GALILEO_IOEXP_J2LO_7BIT_SLAVE_ADDR;
+ }
+
+ //
+ // Set GPIO_SUS<2> as an output, raise voltage to Vdd.
+ //
+ PlatformLegacyGpioSetLevel (R_QNC_GPIO_RGLVL_RESUME_WELL, 2, TRUE);
+
+ //
+ // Select Port 3
+ //
+ Length = 2;
+ Buffer[0] = 0x18; //sub-address
+ Buffer[1] = 0x03; //data
+
+ Status = I2cWriteMultipleByte (
+ I2CSlaveAddress,
+ EfiI2CSevenBitAddrMode,
+ &Length,
+ &Buffer
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Set "Pin Direction" bit4 and bit5 as outputs
+ //
+ Length = 2;
+ Buffer[0] = 0x1C; //sub-address
+ Buffer[1] = 0xCF; //data
+
+ Status = I2cWriteMultipleByte (
+ I2CSlaveAddress,
+ EfiI2CSevenBitAddrMode,
+ &Length,
+ &Buffer
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Lower GPORT3 bit4 and bit5 to Vss
+ //
+ Length = 2;
+ Buffer[0] = 0x0B; //sub-address
+ Buffer[1] = 0xCF; //data
+
+ Status = I2cWriteMultipleByte (
+ I2CSlaveAddress,
+ EfiI2CSevenBitAddrMode,
+ &Length,
+ &Buffer
+ );
+ ASSERT_EFI_ERROR (Status);
+}
+
+VOID
+EFIAPI
+PlatformInitializeUart0MuxGalileoGen2 (
+ VOID
+ )
+/*++
+
+
+Routine Description:
+
+ This is the routine to initialize UART0 on GalileoGen2. The hardware used in this process is
+ I2C controller and the configuring the following IO Expander signal.
+
+ EXP1.P1_5 should be configured as an output & driven high.
+ EXP1.P0_0 should be configured as an output & driven high.
+ EXP0.P1_4 should be configured as an output, driven low.
+ EXP1.P0_1 pullup should be disabled.
+ EXP0.P1_5 Pullup should be disabled.
+
+Arguments:
+
+ None.
+
+Returns:
+
+ None.
+
+--*/
+
+{
+ //
+ // EXP1.P1_5 should be configured as an output & driven high.
+ //
+ PlatformPcal9555GpioSetDir (
+ GALILEO_GEN2_IOEXP1_7BIT_SLAVE_ADDR, // IO Expander 1.
+ 13, // P1-5.
+ TRUE
+ );
+ PlatformPcal9555GpioSetLevel (
+ GALILEO_GEN2_IOEXP1_7BIT_SLAVE_ADDR, // IO Expander 1.
+ 13, // P1-5.
+ TRUE
+ );
+
+ //
+ // EXP1.P0_0 should be configured as an output & driven high.
+ //
+ PlatformPcal9555GpioSetDir (
+ GALILEO_GEN2_IOEXP0_7BIT_SLAVE_ADDR, // IO Expander 0.
+ 0, // P0_0.
+ TRUE
+ );
+ PlatformPcal9555GpioSetLevel (
+ GALILEO_GEN2_IOEXP0_7BIT_SLAVE_ADDR, // IO Expander 0.
+ 0, // P0_0.
+ TRUE
+ );
+
+ //
+ // EXP0.P1_4 should be configured as an output, driven low.
+ //
+ PlatformPcal9555GpioSetDir (
+ GALILEO_GEN2_IOEXP0_7BIT_SLAVE_ADDR, // IO Expander 0.
+ 12, // P1-4.
+ FALSE
+ );
+ PlatformPcal9555GpioSetLevel ( // IO Expander 0.
+ GALILEO_GEN2_IOEXP0_7BIT_SLAVE_ADDR, // P1-4
+ 12,
+ FALSE
+ );
+
+ //
+ // EXP1.P0_1 pullup should be disabled.
+ //
+ PlatformPcal9555GpioDisablePull (
+ GALILEO_GEN2_IOEXP1_7BIT_SLAVE_ADDR, // IO Expander 1.
+ 1 // P0-1.
+ );
+
+ //
+ // EXP0.P1_5 Pullup should be disabled.
+ //
+ PlatformPcal9555GpioDisablePull (
+ GALILEO_GEN2_IOEXP0_7BIT_SLAVE_ADDR, // IO Expander 0.
+ 13 // P1-5.
+ );
+}
+
+VOID
+EFIAPI
+PlatformConfigOnSmmConfigurationProtocol (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+/*++
+
+Routine Description:
+
+ Function runs in PI-DXE to perform platform specific config when
+ SmmConfigurationProtocol is installed.
+
+Arguments:
+ Event - The event that occured.
+ Context - For EFI compatiblity. Not used.
+
+Returns:
+ None.
+--*/
+
+{
+ EFI_STATUS Status;
+ UINT32 NewValue;
+ UINT64 BaseAddress;
+ UINT64 SmramLength;
+ VOID *SmmCfgProt;
+
+ Status = gBS->LocateProtocol (&gEfiSmmConfigurationProtocolGuid, NULL, &SmmCfgProt);
+ if (Status != EFI_SUCCESS){
+ DEBUG ((DEBUG_INFO, "gEfiSmmConfigurationProtocolGuid triggered but not valid.\n"));
+ return;
+ }
+ if (mMemCfgDone) {
+ DEBUG ((DEBUG_INFO, "Platform DXE Mem config already done.\n"));
+ return;
+ }
+
+ //
+ // Disable eSram block (this will also clear/zero eSRAM)
+ // We only use eSRAM in the PEI phase. Disable now that we are in the DXE phase
+ //
+ NewValue = QNCPortRead (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_ESRAMPGCTRL_BLOCK);
+ NewValue |= BLOCK_DISABLE_PG;
+ QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_ESRAMPGCTRL_BLOCK, NewValue);
+
+ //
+ // Update HMBOUND to top of DDR3 memory and LOCK
+ // We disabled eSRAM so now we move HMBOUND down to top of DDR3
+ //
+ QNCGetTSEGMemoryRange (&BaseAddress, &SmramLength);
+ NewValue = (UINT32)(BaseAddress + SmramLength);
+ DEBUG ((EFI_D_INFO,"Locking HMBOUND at: = 0x%8x\n",NewValue));
+ QNCPortWrite (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QUARK_NC_HOST_BRIDGE_HMBOUND_REG, (NewValue | HMBOUND_LOCK));
+
+ //
+ // Lock IMR5 now that HMBOUND is locked (legacy S3 region)
+ //
+ NewValue = QNCPortRead (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR5+QUARK_NC_MEMORY_MANAGER_IMRXL);
+ NewValue |= IMR_LOCK;
+ QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR5+QUARK_NC_MEMORY_MANAGER_IMRXL, NewValue);
+
+ //
+ // Lock IMR6 now that HMBOUND is locked (ACPI Reclaim/ACPI/Runtime services/Reserved)
+ //
+ NewValue = QNCPortRead (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR6+QUARK_NC_MEMORY_MANAGER_IMRXL);
+ NewValue |= IMR_LOCK;
+ QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR6+QUARK_NC_MEMORY_MANAGER_IMRXL, NewValue);
+
+ //
+ // Disable IMR2 memory protection (RMU Main Binary)
+ //
+ QncImrWrite (
+ QUARK_NC_MEMORY_MANAGER_IMR2,
+ (UINT32)(IMRL_RESET & ~IMR_EN),
+ (UINT32)IMRH_RESET,
+ (UINT32)IMRX_ALL_ACCESS,
+ (UINT32)IMRX_ALL_ACCESS
+ );
+
+ //
+ // Disable IMR3 memory protection (Default SMRAM)
+ //
+ QncImrWrite (
+ QUARK_NC_MEMORY_MANAGER_IMR3,
+ (UINT32)(IMRL_RESET & ~IMR_EN),
+ (UINT32)IMRH_RESET,
+ (UINT32)IMRX_ALL_ACCESS,
+ (UINT32)IMRX_ALL_ACCESS
+ );
+
+ //
+ // Disable IMR4 memory protection (eSRAM).
+ //
+ QncImrWrite (
+ QUARK_NC_MEMORY_MANAGER_IMR4,
+ (UINT32)(IMRL_RESET & ~IMR_EN),
+ (UINT32)IMRH_RESET,
+ (UINT32)IMRX_ALL_ACCESS,
+ (UINT32)IMRX_ALL_ACCESS
+ );
+
+ //
+ // RTC:28208 - System hang/crash when entering probe mode(ITP) when relocating SMBASE
+ // Workaround to make default SMRAM UnCachable
+ //
+ Status = gDS->SetMemorySpaceAttributes (
+ (EFI_PHYSICAL_ADDRESS) SMM_DEFAULT_SMBASE,
+ SMM_DEFAULT_SMBASE_SIZE_BYTES,
+ EFI_MEMORY_WB
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ mMemCfgDone = TRUE;
+}
+
+VOID
+EFIAPI
+PlatformConfigOnSpiReady (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+/*++
+
+Routine Description:
+
+ Function runs in PI-DXE to perform platform specific config when SPI
+ interface is ready.
+
+Arguments:
+ Event - The event that occured.
+ Context - For EFI compatiblity. Not used.
+
+Returns:
+ None.
+
+--*/
+{
+ EFI_STATUS Status;
+ VOID *SpiReadyProt = NULL;
+ EFI_PLATFORM_TYPE Type;
+ EFI_BOOT_MODE BootMode;
+
+ BootMode = GetBootModeHob ();
+
+ Status = gBS->LocateProtocol (&gEfiSmmSpiReadyProtocolGuid, NULL, &SpiReadyProt);
+ if (Status != EFI_SUCCESS){
+ DEBUG ((DEBUG_INFO, "gEfiSmmSpiReadyProtocolGuid triggered but not valid.\n"));
+ return;
+ }
+
+ //
+ // Lock regions SPI flash.
+ //
+ PlatformFlashLockPolicy (FALSE);
+
+ //
+ // Configurations and checks to be done when DXE tracing available.
+ //
+
+ //
+ // Platform specific Signal routing.
+ //
+
+ //
+ // Skip any signal not needed for recovery and flash update.
+ //
+ if (BootMode != BOOT_ON_FLASH_UPDATE && BootMode != BOOT_IN_RECOVERY_MODE) {
+
+ //
+ // Galileo Platform UART0 support.
+ //
+ Type = (EFI_PLATFORM_TYPE)PcdGet16 (PcdPlatformType);
+ if (Type == Galileo) {
+ //
+ // Use MUX to connect out UART0 pins.
+ //
+ PlatformInitializeUart0MuxGalileo ();
+ }
+
+ //
+ // GalileoGen2 Platform UART0 support.
+ //
+ if (Type == GalileoGen2) {
+ //
+ // Use route out UART0 pins.
+ //
+ PlatformInitializeUart0MuxGalileoGen2 ();
+ }
+ }
+}
+
+EFI_STATUS
+EFIAPI
+CreateConfigEvents (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+ None
+
+Returns:
+ EFI_STATUS
+
+--*/
+{
+ EFI_EVENT EventSmmCfg;
+ EFI_EVENT EventSpiReady;
+ VOID *RegistrationSmmCfg;
+ VOID *RegistrationSpiReady;
+
+ //
+ // Schedule callback for when SmmConfigurationProtocol installed.
+ //
+ EventSmmCfg = EfiCreateProtocolNotifyEvent (
+ &gEfiSmmConfigurationProtocolGuid,
+ TPL_CALLBACK,
+ PlatformConfigOnSmmConfigurationProtocol,
+ NULL,
+ &RegistrationSmmCfg
+ );
+ ASSERT (EventSmmCfg != NULL);
+
+ //
+ // Schedule callback to setup SPI Flash Policy when SPI interface ready.
+ //
+ EventSpiReady = EfiCreateProtocolNotifyEvent (
+ &gEfiSmmSpiReadyProtocolGuid,
+ TPL_CALLBACK,
+ PlatformConfigOnSpiReady,
+ NULL,
+ &RegistrationSpiReady
+ );
+ ASSERT (EventSpiReady != NULL);
+ return EFI_SUCCESS;
+}
diff --git a/QuarkPlatformPkg/Platform/Dxe/PlatformInit/PlatformInitDxe.c b/QuarkPlatformPkg/Platform/Dxe/PlatformInit/PlatformInitDxe.c
new file mode 100644
index 0000000000..b913d309d6
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Dxe/PlatformInit/PlatformInitDxe.c
@@ -0,0 +1,93 @@
+/** @file
+Platform init DXE driver for this platform.
+
+Copyright (c) 2013 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+//
+// Statements that include other files
+//
+#include "PlatformInitDxe.h"
+#include <Library/PciLib.h>
+#include <IndustryStandard/Pci.h>
+
+VOID
+GetQncName (
+ VOID
+ )
+{
+ DEBUG ((EFI_D_INFO, "QNC Name: "));
+ switch (PciRead16 (PCI_LIB_ADDRESS (MC_BUS, MC_DEV, MC_FUN, PCI_DEVICE_ID_OFFSET))) {
+ case QUARK_MC_DEVICE_ID:
+ DEBUG ((EFI_D_INFO, "Quark"));
+ break;
+ case QUARK2_MC_DEVICE_ID:
+ DEBUG ((EFI_D_INFO, "Quark2"));
+ break;
+ default:
+ DEBUG ((EFI_D_INFO, "Unknown"));
+ }
+
+ //
+ // Revision
+ //
+ switch (PciRead8 (PCI_LIB_ADDRESS (MC_BUS, MC_DEV, MC_FUN, PCI_REVISION_ID_OFFSET))) {
+ case QNC_MC_REV_ID_A0:
+ DEBUG ((EFI_D_INFO, " - A0 stepping\n"));
+ break;
+ default:
+ DEBUG ((EFI_D_INFO, " - xx\n"));
+ }
+
+ return;
+}
+
+EFI_STATUS
+EFIAPI
+PlatformInit (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+/*++
+
+Routine Description:
+ Entry point for the driver.
+
+Arguments:
+
+ ImageHandle - Image Handle.
+ SystemTable - EFI System Table.
+
+Returns:
+
+ EFI_SUCCESS - Function has completed successfully.
+
+--*/
+{
+ EFI_STATUS Status;
+
+ GetQncName();
+
+ //
+ // Create events for configuration callbacks.
+ //
+ CreateConfigEvents ();
+
+ //
+ // Init Platform LEDs.
+ //
+ Status = PlatformLedInit ((EFI_PLATFORM_TYPE)PcdGet16 (PcdPlatformType));
+ ASSERT_EFI_ERROR (Status);
+
+ return EFI_SUCCESS;
+}
+
diff --git a/QuarkPlatformPkg/Platform/Dxe/PlatformInit/PlatformInitDxe.h b/QuarkPlatformPkg/Platform/Dxe/PlatformInit/PlatformInitDxe.h
new file mode 100644
index 0000000000..c8e67f6e1e
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Dxe/PlatformInit/PlatformInitDxe.h
@@ -0,0 +1,64 @@
+/** @file
+Platform init DXE driver header file.
+
+Copyright (c) 2013 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _PLATFORM_TYPES_H_
+#define _PLATFORM_TYPES_H_
+
+#include <PiDxe.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/HobLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/PlatformHelperLib.h>
+#include <Library/PlatformPcieHelperLib.h>
+#include <Library/IntelQNCLib.h>
+#include <Library/QNCAccessLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/I2cLib.h>
+#include <Protocol/Variable.h>
+#include <Protocol/Cpu.h>
+#include <Protocol/PciEnumerationComplete.h>
+#include <Protocol/Spi.h>
+#include <Protocol/PlatformSmmSpiReady.h>
+#include <Protocol/SmmConfiguration.h>
+#include <Guid/HobList.h>
+#include <IntelQNCRegs.h>
+#include <Platform.h>
+#include <Pcal9555.h>
+#include <PlatformBoards.h>
+#include <IohAccess.h>
+
+#define BLOCK_SIZE_32KB 0x8000
+#define BLOCK_SIZE_64KB 0x10000
+
+//
+// Function prototypes for routines private to this driver.
+//
+EFI_STATUS
+EFIAPI
+CreateConfigEvents (
+ VOID
+ );
+
+EFI_STATUS
+EFIAPI
+PlatformPcal9555Config (
+ IN CONST EFI_PLATFORM_TYPE PlatformType
+ );
+
+#endif
diff --git a/QuarkPlatformPkg/Platform/Dxe/PlatformInit/PlatformInitDxe.inf b/QuarkPlatformPkg/Platform/Dxe/PlatformInit/PlatformInitDxe.inf
new file mode 100644
index 0000000000..05f13236f3
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Dxe/PlatformInit/PlatformInitDxe.inf
@@ -0,0 +1,62 @@
+## @file
+# Component description file for Quark Platform Init DXE module.
+#
+# Copyright (c) 2013 Intel Corporation.
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = PlatformInitDxe
+ FILE_GUID = 2E6A521C-F697-402d-9774-98B2B7E140F3
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = PlatformInit
+
+[Sources]
+ PlatformInitDxe.h
+ PlatformInitDxe.c
+ PlatformConfig.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ QuarkSocPkg/QuarkSocPkg.dec
+ QuarkPlatformPkg/QuarkPlatformPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ HobLib
+ DebugLib
+ UefiDriverEntryPoint
+ UefiBootServicesTableLib
+ UefiRuntimeServicesTableLib
+ DxeServicesTableLib
+ PlatformHelperLib
+ PlatformPcieHelperLib
+ DxeServicesLib
+ IntelQNCLib
+ QNCAccessLib
+ BaseMemoryLib
+ I2cLib
+
+[Protocols]
+ gEfiFirmwareVolumeBlockProtocolGuid
+ gEfiCpuArchProtocolGuid
+ gEfiSmmConfigurationProtocolGuid
+ gEfiSmmSpiReadyProtocolGuid
+
+[Pcd]
+ gQuarkPlatformTokenSpaceGuid.PcdPlatformType
+
+[Depex]
+ TRUE
+
diff --git a/QuarkPlatformPkg/Platform/Dxe/SaveMemoryConfig/SaveMemoryConfig.c b/QuarkPlatformPkg/Platform/Dxe/SaveMemoryConfig/SaveMemoryConfig.c
new file mode 100644
index 0000000000..f041b03077
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Dxe/SaveMemoryConfig/SaveMemoryConfig.c
@@ -0,0 +1,124 @@
+/** @file
+This is the driver that locates the MemoryConfigurationData HOB, if it
+exists, and saves the data to nvRAM.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+
+#include <Guid/MemoryConfigData.h>
+#include <Guid/DebugMask.h>
+
+EFI_STATUS
+EFIAPI
+SaveMemoryConfigEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+/*++
+
+ Routine Description:
+ This is the standard EFI driver point that detects whether there is a
+ MemoryConfigurationData HOB and, if so, saves its data to nvRAM.
+
+ Arguments:
+ ImageHandle - Handle for the image of this driver
+ SystemTable - Pointer to the EFI System Table
+
+ Returns:
+ EFI_SUCCESS - if the data is successfully saved or there was no data
+ EFI_NOT_FOUND - if the HOB list could not be located.
+ EFI_UNLOAD_IMAGE - It is not success
+
+--*/
+{
+ EFI_STATUS Status;
+ VOID *HobList;
+ EFI_HOB_GUID_TYPE *GuidHob;
+ VOID *HobData;
+ VOID *VariableData;
+ UINTN DataSize;
+ UINTN BufferSize;
+
+ DataSize = 0;
+ VariableData = NULL;
+ GuidHob = NULL;
+ HobList = NULL;
+ HobData = NULL;
+ Status = EFI_UNSUPPORTED;
+
+ //
+ // Get the HOB list. If it is not present, then ASSERT.
+ //
+ HobList = GetHobList ();
+ ASSERT (HobList != NULL);
+
+ //
+ // Search for the Memory Configuration GUID HOB. If it is not present, then
+ // there's nothing we can do. It may not exist on the update path.
+ //
+ GuidHob = GetNextGuidHob (&gEfiMemoryConfigDataGuid, HobList);
+ if (GuidHob != NULL) {
+ HobData = GET_GUID_HOB_DATA (GuidHob);
+ DataSize = GET_GUID_HOB_DATA_SIZE (GuidHob);
+ //
+ // Use the HOB to save Memory Configuration Data
+ //
+ BufferSize = DataSize;
+ VariableData = AllocatePool (BufferSize);
+ ASSERT (VariableData != NULL);
+ Status = gRT->GetVariable (
+ EFI_MEMORY_CONFIG_DATA_NAME,
+ &gEfiMemoryConfigDataGuid,
+ NULL,
+ &BufferSize,
+ VariableData
+ );
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ gBS->FreePool (VariableData);
+ VariableData = AllocatePool (BufferSize);
+ ASSERT (VariableData != NULL);
+ Status = gRT->GetVariable (
+ EFI_MEMORY_CONFIG_DATA_NAME,
+ &gEfiMemoryConfigDataGuid,
+ NULL,
+ &BufferSize,
+ VariableData
+ );
+ }
+
+ if (EFI_ERROR(Status) || BufferSize != DataSize || CompareMem (HobData, VariableData, DataSize) != 0) {
+ Status = gRT->SetVariable (
+ EFI_MEMORY_CONFIG_DATA_NAME,
+ &gEfiMemoryConfigDataGuid,
+ (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS),
+ DataSize,
+ HobData
+ );
+ ASSERT((Status == EFI_SUCCESS) || (Status == EFI_OUT_OF_RESOURCES));
+ }
+
+ gBS->FreePool (VariableData);
+ }
+
+ //
+ // This driver does not produce any protocol services, so always unload it.
+ //
+ return Status;
+}
diff --git a/QuarkPlatformPkg/Platform/Dxe/SaveMemoryConfig/SaveMemoryConfig.inf b/QuarkPlatformPkg/Platform/Dxe/SaveMemoryConfig/SaveMemoryConfig.inf
new file mode 100644
index 0000000000..277583262c
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Dxe/SaveMemoryConfig/SaveMemoryConfig.inf
@@ -0,0 +1,50 @@
+## @file
+# Component description file for SaveMemoryConfig module
+#
+# Copyright (c) 2013-2015 Intel Corporation.
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = SaveMemoryConfig
+ FILE_GUID = 0F99E33C-CA0C-4aa2-887D-B57EC9050278
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = SaveMemoryConfigEntryPoint
+
+[sources]
+ SaveMemoryConfig.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ QuarkPlatformPkg/QuarkPlatformPkg.dec
+
+[LibraryClasses]
+ DebugLib
+ MemoryAllocationLib
+ BaseMemoryLib
+ UefiRuntimeServicesTableLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+ HobLib
+
+[Protocols]
+
+[Guids]
+ gEfiGenericVariableGuid
+ gEfiMemoryConfigDataGuid
+
+[Depex]
+ gEdkiiVariableLockProtocolGuid AND
+ gEfiVariableArchProtocolGuid AND
+ gEfiVariableWriteArchProtocolGuid
diff --git a/QuarkPlatformPkg/Platform/Dxe/Setup/CommonHeader.h b/QuarkPlatformPkg/Platform/Dxe/Setup/CommonHeader.h
new file mode 100644
index 0000000000..f346f8650a
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Dxe/Setup/CommonHeader.h
@@ -0,0 +1,61 @@
+/** @file
+Common header file shared by all source files.
+
+This file includes package header files, library classes and protocol, PPI & GUID definitions.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+
+#ifndef __COMMON_HEADER_H_
+#define __COMMON_HEADER_H_
+
+
+
+#include <PiDxe.h>
+#include <IntelQNCDxe.h>
+#include <IndustryStandard/Pci22.h>
+
+#include <Guid/MdeModuleHii.h>
+#include <Protocol/Smbios.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/DiskInfo.h>
+#include <Protocol/PlatformPolicy.h>
+#include <Protocol/MpService.h>
+
+#include <Protocol/HiiString.h>
+#include <Protocol/HiiDatabase.h>
+#include <Protocol/HiiConfigRouting.h>
+#include <Protocol/HiiConfigAccess.h>
+
+#include <Protocol/IdeControllerInit.h>
+#include <Protocol/PciIo.h>
+
+#include <Library/BaseLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/S3BootScriptLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/HiiLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PrintLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IntelQNCLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciLib.h>
+#include <Library/S3IoLib.h>
+#include <Library/S3PciLib.h>
+#include <Library/DevicePathLib.h>
+
+#endif
diff --git a/QuarkPlatformPkg/Platform/Dxe/Setup/DxePlatform.inf b/QuarkPlatformPkg/Platform/Dxe/Setup/DxePlatform.inf
new file mode 100644
index 0000000000..c58b3b099e
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Dxe/Setup/DxePlatform.inf
@@ -0,0 +1,82 @@
+## @file
+# Component description file for DxePlatform module.
+#
+# This driver initializes platform configuration setting and installs several platform policy potocols.
+# Copyright (c) 2013-2015 Intel Corporation.
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = DxePlatform
+ FILE_GUID = DAA55048-BC3F-4dd9-999B-F58ABF2BBFCC
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = DxePlatformDriverEntry
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[Sources]
+ KeyboardLayout.c
+ QNCRegTable.c
+ processor.c
+ SetupPlatform.c
+ SetupPlatform.h
+ Strings.uni
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ QuarkPlatformPkg/QuarkPlatformPkg.dec
+ QuarkSocPkg/QuarkSocPkg.dec
+
+[LibraryClasses]
+ IoLib
+ IntelQNCLib
+ PcdLib
+ PrintLib
+ MemoryAllocationLib
+ BaseMemoryLib
+ S3BootScriptLib
+ DebugLib
+ UefiRuntimeServicesTableLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+ BaseLib
+ S3IoLib
+ S3PciLib
+ HiiLib
+ HobLib
+ PciLib
+ UefiLib
+
+[Guids]
+
+[Protocols]
+ gEfiPlatformPolicyProtocolGuid # PROTOCOL ALWAYS_PRODUCED
+ gEfiHiiDatabaseProtocolGuid # PROTOCOL ALWAYS_CONSUMED
+ gEfiHiiConfigAccessProtocolGuid # PROTOCOL ALWAYS_CONSUMED
+ gEfiHiiConfigRoutingProtocolGuid # PROTOCOL ALWAYS_CONSUMED
+
+[Pcd]
+ gEfiQuarkNcSocIdTokenSpaceGuid.PcdRcbaMmioBaseAddress
+ gEfiQuarkNcSocIdTokenSpaceGuid.PcdQuarkAgent0IR
+ gEfiQuarkNcSocIdTokenSpaceGuid.PcdQuarkAgent1IR
+ gEfiQuarkNcSocIdTokenSpaceGuid.PcdQuarkAgent2IR
+ gEfiQuarkNcSocIdTokenSpaceGuid.PcdQuarkAgent3IR
+
+[Depex]
+ # AND EFI_SDRAM_MEMORY_SETUP_PROTOCOL_GUID AND
+ gEfiVariableArchProtocolGuid AND gEfiVariableWriteArchProtocolGuid AND gEfiHiiDatabaseProtocolGuid AND gPcdProtocolGuid
diff --git a/QuarkPlatformPkg/Platform/Dxe/Setup/KeyboardLayout.c b/QuarkPlatformPkg/Platform/Dxe/Setup/KeyboardLayout.c
new file mode 100644
index 0000000000..84fbbab7fc
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Dxe/Setup/KeyboardLayout.c
@@ -0,0 +1,268 @@
+/** @file
+Example code to register customized keyboard layout to HII database.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "CommonHeader.h"
+
+//
+// Define "`" as Non-spacing key to switch "a","u","i","o","e"
+//
+#define ENABLE_NS_KEY 1
+
+#ifdef ENABLE_NS_KEY
+#define KEYBOARD_KEY_COUNT (104 + 5)
+#else
+#define KEYBOARD_KEY_COUNT 104
+#endif
+
+#pragma pack (1)
+typedef struct {
+ //
+ // This 4-bytes total array length is required by PreparePackageList()
+ //
+ UINT32 Length;
+
+ //
+ // Keyboard Layout package definition
+ //
+ EFI_HII_PACKAGE_HEADER PackageHeader;
+ UINT16 LayoutCount;
+
+ //
+ // EFI_HII_KEYBOARD_LAYOUT
+ //
+ UINT16 LayoutLength;
+ EFI_GUID Guid;
+ UINT32 LayoutDescriptorStringOffset;
+ UINT8 DescriptorCount;
+ EFI_KEY_DESCRIPTOR KeyDescriptor[KEYBOARD_KEY_COUNT];
+ UINT16 DescriptionCount; // EFI_DESCRIPTION_STRING_BUNDLE
+ CHAR16 Language[5]; // RFC4646 Language Code: "en-US"
+ CHAR16 Space;
+ CHAR16 DescriptionString[17]; // Description: "English Keyboard"
+} KEYBOARD_LAYOUT_PACK_BIN;
+#pragma pack()
+
+#define KEYBOARD_LAYOUT_PACKAGE_GUID \
+ { \
+ 0xd66f7b7a, 0x5e06, 0x49f3, { 0xa1, 0xcf, 0x12, 0x8d, 0x4, 0x86, 0xc2, 0x7c } \
+ }
+
+#define KEYBOARD_LAYOUT_KEY_GUID \
+ { \
+ 0xd9db96f4, 0xff47, 0x4eb6, { 0x8a, 0x4, 0x79, 0x5b, 0x56, 0x87, 0xb, 0x4e } \
+ }
+
+EFI_GUID mKeyboardLayoutPackageGuid = KEYBOARD_LAYOUT_PACKAGE_GUID;
+EFI_GUID mKeyboardLayoutKeyGuid = KEYBOARD_LAYOUT_KEY_GUID;
+
+KEYBOARD_LAYOUT_PACK_BIN mKeyboardLayoutBin = {
+ sizeof (KEYBOARD_LAYOUT_PACK_BIN), // Binary size
+
+ //
+ // EFI_HII_PACKAGE_HEADER
+ //
+ {
+ sizeof (KEYBOARD_LAYOUT_PACK_BIN) - sizeof (UINT32),
+ EFI_HII_PACKAGE_KEYBOARD_LAYOUT
+ },
+ 1, // LayoutCount
+ sizeof (KEYBOARD_LAYOUT_PACK_BIN) - sizeof (UINT32) - sizeof (EFI_HII_PACKAGE_HEADER) - sizeof (UINT16), // LayoutLength
+ KEYBOARD_LAYOUT_KEY_GUID, // KeyGuid
+ sizeof (UINT16) + sizeof (EFI_GUID) + sizeof (UINT32) + sizeof (UINT8) + (KEYBOARD_KEY_COUNT * sizeof (EFI_KEY_DESCRIPTOR)), // LayoutDescriptorStringOffset
+ KEYBOARD_KEY_COUNT, // DescriptorCount
+ {
+ //
+ // EFI_KEY_DESCRIPTOR
+ //
+ {EfiKeyC1, 'a', 'A', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+ {EfiKeyB5, 'b', 'B', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+ {EfiKeyB3, 'c', 'C', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+ {EfiKeyC3, 'd', 'D', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+ {EfiKeyD3, 'e', 'E', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+ {EfiKeyC4, 'f', 'F', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+ {EfiKeyC5, 'g', 'G', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+ {EfiKeyC6, 'h', 'H', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+ {EfiKeyD8, 'i', 'I', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+ {EfiKeyC7, 'j', 'J', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+ {EfiKeyC8, 'k', 'K', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+ {EfiKeyC9, 'l', 'L', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+ {EfiKeyB7, 'm', 'M', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+ {EfiKeyB6, 'n', 'N', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+ {EfiKeyD9, 'o', 'O', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+ {EfiKeyD10, 'p', 'P', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+ {EfiKeyD1, 'q', 'Q', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+ {EfiKeyD4, 'r', 'R', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+ {EfiKeyC2, 's', 'S', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+ {EfiKeyD5, 't', 'T', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+ {EfiKeyD7, 'u', 'U', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+ {EfiKeyB4, 'v', 'V', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+ {EfiKeyD2, 'w', 'W', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+ {EfiKeyB2, 'x', 'X', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+ {EfiKeyD6, 'y', 'Y', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+ {EfiKeyB1, 'z', 'Z', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+ {EfiKeyE1, '1', '!', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},
+ {EfiKeyE2, '2', '@', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},
+ {EfiKeyE3, '3', '#', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},
+ {EfiKeyE4, '4', '$', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},
+ {EfiKeyE5, '5', '%', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},
+ {EfiKeyE6, '6', '^', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},
+ {EfiKeyE7, '7', '&', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},
+ {EfiKeyE8, '8', '*', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},
+ {EfiKeyE9, '9', '(', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},
+ {EfiKeyE10, '0', ')', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},
+ {EfiKeyEnter, 0x0d, 0x0d, 0, 0, EFI_NULL_MODIFIER, 0},
+ {EfiKeyEsc, 0x1b, 0x1b, 0, 0, EFI_NULL_MODIFIER, 0},
+ {EfiKeyBackSpace, 0x08, 0x08, 0, 0, EFI_NULL_MODIFIER, 0},
+ {EfiKeyTab, 0x09, 0x09, 0, 0, EFI_NULL_MODIFIER, 0},
+ {EfiKeySpaceBar, ' ', ' ', 0, 0, EFI_NULL_MODIFIER, 0},
+ {EfiKeyE11, '-', '_', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},
+ {EfiKeyE12, '=', '+', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},
+ {EfiKeyD11, '[', '{', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},
+ {EfiKeyD12, ']', '}', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},
+ {EfiKeyD13, '\\', '|', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},
+ {EfiKeyC10, ';', ':', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},
+ {EfiKeyC11, '\'', '"', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},
+
+#ifdef ENABLE_NS_KEY
+ //
+ // Non-Spacing key example
+ //
+ {EfiKeyE0, 0, 0, 0, 0, EFI_NS_KEY_MODIFIER, 0},
+ {EfiKeyC1, 0x00E2, 0x00C2, 0, 0, EFI_NS_KEY_DEPENDENCY_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+ {EfiKeyD3, 0x00EA, 0x00CA, 0, 0, EFI_NS_KEY_DEPENDENCY_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+ {EfiKeyD8, 0x00EC, 0x00CC, 0, 0, EFI_NS_KEY_DEPENDENCY_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+ {EfiKeyD9, 0x00F4, 0x00D4, 0, 0, EFI_NS_KEY_DEPENDENCY_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+ {EfiKeyD7, 0x00FB, 0x00CB, 0, 0, EFI_NS_KEY_DEPENDENCY_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
+#else
+ {EfiKeyE0, '`', '~', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},
+#endif
+
+ {EfiKeyB8, ',', '<', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},
+ {EfiKeyB9, '.', '>', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},
+ {EfiKeyB10, '/', '?', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},
+ {EfiKeyCapsLock, 0x00, 0x00, 0, 0, EFI_CAPS_LOCK_MODIFIER, 0},
+ {EfiKeyF1, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_ONE_MODIFIER, 0},
+ {EfiKeyF2, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_TWO_MODIFIER, 0},
+ {EfiKeyF3, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_THREE_MODIFIER, 0},
+ {EfiKeyF4, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_FOUR_MODIFIER, 0},
+ {EfiKeyF5, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_FIVE_MODIFIER, 0},
+ {EfiKeyF6, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_SIX_MODIFIER, 0},
+ {EfiKeyF7, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_SEVEN_MODIFIER, 0},
+ {EfiKeyF8, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_EIGHT_MODIFIER, 0},
+ {EfiKeyF9, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_NINE_MODIFIER, 0},
+ {EfiKeyF10, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_TEN_MODIFIER, 0},
+ {EfiKeyF11, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_ELEVEN_MODIFIER, 0},
+ {EfiKeyF12, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_TWELVE_MODIFIER, 0},
+ {EfiKeyPrint, 0x00, 0x00, 0, 0, EFI_PRINT_MODIFIER, 0},
+ {EfiKeySLck, 0x00, 0x00, 0, 0, EFI_SCROLL_LOCK_MODIFIER, 0},
+ {EfiKeyPause, 0x00, 0x00, 0, 0, EFI_PAUSE_MODIFIER, 0},
+ {EfiKeyIns, 0x00, 0x00, 0, 0, EFI_INSERT_MODIFIER, 0},
+ {EfiKeyHome, 0x00, 0x00, 0, 0, EFI_HOME_MODIFIER, 0},
+ {EfiKeyPgUp, 0x00, 0x00, 0, 0, EFI_PAGE_UP_MODIFIER, 0},
+ {EfiKeyDel, 0x00, 0x00, 0, 0, EFI_DELETE_MODIFIER, 0},
+ {EfiKeyEnd, 0x00, 0x00, 0, 0, EFI_END_MODIFIER, 0},
+ {EfiKeyPgDn, 0x00, 0x00, 0, 0, EFI_PAGE_DOWN_MODIFIER, 0},
+ {EfiKeyRightArrow, 0x00, 0x00, 0, 0, EFI_RIGHT_ARROW_MODIFIER, 0},
+ {EfiKeyLeftArrow, 0x00, 0x00, 0, 0, EFI_LEFT_ARROW_MODIFIER, 0},
+ {EfiKeyDownArrow, 0x00, 0x00, 0, 0, EFI_DOWN_ARROW_MODIFIER, 0},
+ {EfiKeyUpArrow, 0x00, 0x00, 0, 0, EFI_UP_ARROW_MODIFIER, 0},
+ {EfiKeyNLck, 0x00, 0x00, 0, 0, EFI_NUM_LOCK_MODIFIER, 0},
+ {EfiKeySlash, '/', '/', 0, 0, EFI_NULL_MODIFIER, 0},
+ {EfiKeyAsterisk, '*', '*', 0, 0, EFI_NULL_MODIFIER, 0},
+ {EfiKeyMinus, '-', '-', 0, 0, EFI_NULL_MODIFIER, 0},
+ {EfiKeyPlus, '+', '+', 0, 0, EFI_NULL_MODIFIER, 0},
+ {EfiKeyEnter, 0x0d, 0x0d, 0, 0, EFI_NULL_MODIFIER, 0},
+ {EfiKeyOne, '1', '1', 0, 0, EFI_END_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},
+ {EfiKeyTwo, '2', '2', 0, 0, EFI_DOWN_ARROW_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},
+ {EfiKeyThree, '3', '3', 0, 0, EFI_PAGE_DOWN_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},
+ {EfiKeyFour, '4', '4', 0, 0, EFI_LEFT_ARROW_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},
+ {EfiKeyFive, '5', '5', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},
+ {EfiKeySix, '6', '6', 0, 0, EFI_RIGHT_ARROW_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},
+ {EfiKeySeven, '7', '7', 0, 0, EFI_HOME_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},
+ {EfiKeyEight, '8', '8', 0, 0, EFI_UP_ARROW_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},
+ {EfiKeyNine, '9', '9', 0, 0, EFI_PAGE_UP_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},
+ {EfiKeyZero, '0', '0', 0, 0, EFI_INSERT_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},
+ {EfiKeyPeriod, '.', '.', 0, 0, EFI_DELETE_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},
+ {EfiKeyA4, 0x00, 0x00, 0, 0, EFI_MENU_MODIFIER, 0},
+ {EfiKeyLCtrl, 0, 0, 0, 0, EFI_LEFT_CONTROL_MODIFIER, 0},
+ {EfiKeyLShift, 0, 0, 0, 0, EFI_LEFT_SHIFT_MODIFIER, 0},
+ {EfiKeyLAlt, 0, 0, 0, 0, EFI_LEFT_ALT_MODIFIER, 0},
+ {EfiKeyA0, 0, 0, 0, 0, EFI_LEFT_LOGO_MODIFIER, 0},
+ {EfiKeyRCtrl, 0, 0, 0, 0, EFI_RIGHT_CONTROL_MODIFIER, 0},
+ {EfiKeyRShift, 0, 0, 0, 0, EFI_RIGHT_SHIFT_MODIFIER, 0},
+ {EfiKeyA2, 0, 0, 0, 0, EFI_RIGHT_ALT_MODIFIER, 0},
+ {EfiKeyA3, 0, 0, 0, 0, EFI_RIGHT_LOGO_MODIFIER, 0},
+ },
+ 1, // DescriptionCount
+ {'e', 'n', '-', 'U', 'S'}, // RFC4646 language code
+ ' ', // Space
+ {'E', 'n', 'g', 'l', 'i', 's', 'h', ' ', 'K', 'e', 'y', 'b', 'o', 'a', 'r', 'd', '\0'}, // DescriptionString[17]
+};
+
+extern EFI_HANDLE mImageHandle;
+
+EFI_STATUS
+InitKeyboardLayout (
+ VOID
+ )
+/*++
+
+ Routine Description:
+ Install keyboard layout package and set current keyboard layout.
+
+ Arguments:
+ None.
+
+ Returns:
+ EFI_STATUS
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_HII_DATABASE_PROTOCOL *HiiDatabase;
+ EFI_HII_HANDLE HiiHandle;
+
+ //
+ // Locate Hii database protocol
+ //
+ Status = gBS->LocateProtocol (
+ &gEfiHiiDatabaseProtocolGuid,
+ NULL,
+ (VOID**)&HiiDatabase
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Install Keyboard Layout package to HII database
+ //
+ HiiHandle = HiiAddPackages (
+ &mKeyboardLayoutPackageGuid,
+ mImageHandle,
+ &mKeyboardLayoutBin,
+ NULL
+ );
+ if (HiiHandle == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Set current keyboard layout
+ //
+ Status = HiiDatabase->SetKeyboardLayout (HiiDatabase, &mKeyboardLayoutKeyGuid);
+
+ return Status;
+}
diff --git a/QuarkPlatformPkg/Platform/Dxe/Setup/QNCRegTable.c b/QuarkPlatformPkg/Platform/Dxe/Setup/QNCRegTable.c
new file mode 100644
index 0000000000..9a834ee6be
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Dxe/Setup/QNCRegTable.c
@@ -0,0 +1,86 @@
+/** @file
+Register initialization table for Ich.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+
+**/
+
+
+#include "CommonHeader.h"
+
+VOID
+PlatformInitQNCRegs (
+ VOID
+ )
+{
+ //
+ // All devices on bus 0.
+ // Device 0:
+ // FNC 0: Host Bridge
+ // Device 20:
+ // FNC 0: IOSF2AHB Bridge
+ // Device 21:
+ // FNC 0: IOSF2AHB Bridge
+ // Device 23:
+ // FNC 0: PCIe Port 0
+ // Device 24:
+ // FNC 0: PCIe Port 1
+
+ // Device 31:
+ // FNC 0: PCI-LPC Bridge
+ //
+ S3PciWrite32 (PCI_LIB_ADDRESS (PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_QNC_LPC, PCI_FUNCTION_NUMBER_QNC_LPC, R_QNC_LPC_FWH_BIOS_DEC),
+ B_QNC_LPC_FWH_BIOS_DEC_F0 | B_QNC_LPC_FWH_BIOS_DEC_F8 |
+ B_QNC_LPC_FWH_BIOS_DEC_E0 | B_QNC_LPC_FWH_BIOS_DEC_E8 |
+ B_QNC_LPC_FWH_BIOS_DEC_D0 | B_QNC_LPC_FWH_BIOS_DEC_D8 |
+ B_QNC_LPC_FWH_BIOS_DEC_C0 | B_QNC_LPC_FWH_BIOS_DEC_C8
+ );
+
+ //
+ // Program SCI Interrupt for IRQ9
+ //
+ S3PciWrite8 (PCI_LIB_ADDRESS (PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_QNC_LPC, PCI_FUNCTION_NUMBER_QNC_LPC, R_QNC_LPC_ACTL),
+ V_QNC_LPC_ACTL_SCIS_IRQ9
+ );
+
+ //
+ // Program Quark Interrupt Route Registers
+ //
+ S3MmioWrite16 ((UINTN)PcdGet64(PcdRcbaMmioBaseAddress) + R_QNC_RCRB_AGENT0IR,
+ PcdGet16(PcdQuarkAgent0IR)
+ );
+ S3MmioWrite16 ((UINTN)PcdGet64(PcdRcbaMmioBaseAddress) + R_QNC_RCRB_AGENT1IR,
+ PcdGet16(PcdQuarkAgent1IR)
+ );
+ S3MmioWrite16 ((UINTN)PcdGet64(PcdRcbaMmioBaseAddress) + R_QNC_RCRB_AGENT2IR,
+ PcdGet16(PcdQuarkAgent2IR)
+ );
+ S3MmioWrite16 ((UINTN)PcdGet64(PcdRcbaMmioBaseAddress) + R_QNC_RCRB_AGENT3IR,
+ PcdGet16(PcdQuarkAgent3IR)
+ );
+
+ //
+ // Program SVID and SID for QNC PCI devices. In order to boost performance, we
+ // combine two 16 bit PCI_WRITE into one 32 bit PCI_WRITE. The programmed LPC SVID
+ // will reflect on all internal devices's SVID registers
+ //
+ S3PciWrite32 (PCI_LIB_ADDRESS (PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_QNC_LPC, PCI_FUNCTION_NUMBER_QNC_LPC, R_EFI_PCI_SVID),
+ (UINT32)(V_INTEL_VENDOR_ID + (QUARK_V_LPC_DEVICE_ID_0 << 16))
+ );
+
+ //
+ // Write once on Element Self Description Register before OS boot
+ //
+ QNCMmio32And (PcdGet64(PcdRcbaMmioBaseAddress), 0x04, 0xFF00FFFF);
+
+ return;
+}
diff --git a/QuarkPlatformPkg/Platform/Dxe/Setup/SetupPlatform.c b/QuarkPlatformPkg/Platform/Dxe/Setup/SetupPlatform.c
new file mode 100644
index 0000000000..e705f1ba64
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Dxe/Setup/SetupPlatform.c
@@ -0,0 +1,103 @@
+/** @file
+Platform Initialization Driver.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "CommonHeader.h"
+
+#include "SetupPlatform.h"
+#include <Library/HobLib.h>
+
+EFI_HANDLE mImageHandle = NULL;
+
+EFI_HII_DATABASE_PROTOCOL *mHiiDataBase = NULL;
+EFI_HII_CONFIG_ROUTING_PROTOCOL *mHiiConfigRouting = NULL;
+
+UINT8 mSmbusRsvdAddresses[PLATFORM_NUM_SMBUS_RSVD_ADDRESSES] = {
+ SMBUS_ADDR_CH_A_1,
+ SMBUS_ADDR_CK505,
+ SMBUS_ADDR_THERMAL_SENSOR1,
+ SMBUS_ADDR_THERMAL_SENSOR2
+};
+
+EFI_PLATFORM_POLICY_PROTOCOL mPlatformPolicyData = {
+ PLATFORM_NUM_SMBUS_RSVD_ADDRESSES,
+ mSmbusRsvdAddresses
+};
+
+EFI_STATUS
+DxePlatformDriverEntry (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+/*++
+
+ Routine Description:
+ This is the standard EFI driver point for the D845GRgPlatform Driver. This
+ driver is responsible for setting up any platform specific policy or
+ initialization information.
+
+ Arguments:
+ ImageHandle - Handle for the image of this driver
+ SystemTable - Pointer to the EFI System Table
+
+ Returns:
+ EFI_SUCCESS - Policy decisions set
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_HANDLE Handle;
+
+ S3BootScriptSaveInformationAsciiString (
+ "SetupDxeEntryBegin"
+ );
+
+ mImageHandle = ImageHandle;
+
+ Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID**)&mHiiDataBase);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID**)&mHiiConfigRouting);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Initialize keyboard layout
+ //
+ Status = InitKeyboardLayout ();
+
+ //
+ // Initialize ICH registers
+ //
+ PlatformInitQNCRegs();
+
+ ProducePlatformCpuData ();
+
+ //
+ // Install protocol to to allow access to this Policy.
+ //
+ Handle = NULL;
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &Handle,
+ &gEfiPlatformPolicyProtocolGuid, &mPlatformPolicyData,
+ NULL
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ S3BootScriptSaveInformationAsciiString (
+ "SetupDxeEntryEnd"
+ );
+
+ return EFI_SUCCESS;
+}
+
diff --git a/QuarkPlatformPkg/Platform/Dxe/Setup/SetupPlatform.h b/QuarkPlatformPkg/Platform/Dxe/Setup/SetupPlatform.h
new file mode 100644
index 0000000000..85fc6905a3
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Dxe/Setup/SetupPlatform.h
@@ -0,0 +1,77 @@
+/** @file
+Header file for Platform Initialization Driver.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _SETUP_PLATFORM_H
+#define _SETUP_PLATFORM_H
+
+//
+// Data
+//
+#define PLATFORM_NUM_SMBUS_RSVD_ADDRESSES 4
+#define VAR_OFFSET(Field) ((UINT16) ((UINTN) &(((SYSTEM_CONFIGURATION *) 0)->Field)))
+#define QUESTION_ID(Field) (VAR_OFFSET (Field) + 1)
+
+#define SMBUS_ADDR_CH_A_1 0xA0
+#define SMBUS_ADDR_CK505 0xD2
+#define SMBUS_ADDR_THERMAL_SENSOR1 0x4C
+#define SMBUS_ADDR_THERMAL_SENSOR2 0x4D
+
+///
+/// HII specific Vendor Device Path Node definition.
+///
+#pragma pack(1)
+
+typedef struct {
+ VENDOR_DEVICE_PATH VendorDevicePath;
+ UINT16 UniqueId;
+} HII_VENDOR_DEVICE_PATH_NODE;
+
+///
+/// HII specific Vendor Device Path definition.
+///
+typedef struct {
+ HII_VENDOR_DEVICE_PATH_NODE Node;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} HII_VENDOR_DEVICE_PATH;
+
+#pragma pack()
+
+//
+// Prototypes
+//
+VOID
+ProducePlatformCpuData (
+ VOID
+ );
+
+VOID
+PlatformInitQNCRegs (
+ VOID
+ );
+
+EFI_STATUS
+InitKeyboardLayout (
+ VOID
+ );
+
+//
+// Global externs
+//
+extern UINT8 UefiSetupDxeStrings[];
+
+extern EFI_HII_DATABASE_PROTOCOL *mHiiDataBase;
+extern EFI_HII_CONFIG_ROUTING_PROTOCOL *mHiiConfigRouting;
+
+#endif
diff --git a/QuarkPlatformPkg/Platform/Dxe/Setup/Strings.uni b/QuarkPlatformPkg/Platform/Dxe/Setup/Strings.uni
new file mode 100644
index 0000000000..ec13681f9c
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Dxe/Setup/Strings.uni
@@ -0,0 +1,53 @@
+// /** @file
+// String definitions for Sample Setup formset.
+//
+// Copyright (c) 2013-2015 Intel Corporation.
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+//
+// **/
+
+/=#
+
+#langdef en-US "English"
+#langdef fr-FR "Français"
+#langdef es-ES "Español"
+
+#string STR_LGA775 #language en-US "L775"
+#string STR_LGA775 #language fr-FR "L775"
+#string STR_LGA775 #language es-ES "L775"
+
+
+// Enable or Disable
+#string STR_ENABLE #language en-US "Enable"
+#string STR_ENABLE #language fr-FR "Activé"
+#string STR_ENABLE #language es-ES "Activada"
+
+#string STR_DISABLE #language en-US "Disable"
+#string STR_DISABLE #language fr-FR "Désactivé"
+#string STR_DISABLE #language es-ES "Desactivada"
+
+#string STR_AUTO #language en-US "Auto"
+#string STR_AUTO #language fr-FR "Auto"
+#string STR_AUTO #language es-ES "Auto"
+
+// Unknown
+#string STR_UNKNOWN #language en-US "Unknown"
+#string STR_UNKNOWN #language fr-FR "Unknown"
+#string STR_UNKNOWN #language es-ES "Unknown"
+
+
+// NULL String
+#string STR_NULL_STRING #language en-US ""
+
+#string STR_VAR_TOTAL_MEMORY_SIZE #language en-US "54"
+
+#string VAR_EQ_CONFIG_MODE_NAME #language en-US "67"
+// End of file
diff --git a/QuarkPlatformPkg/Platform/Dxe/Setup/processor.c b/QuarkPlatformPkg/Platform/Dxe/Setup/processor.c
new file mode 100644
index 0000000000..dee10f1e19
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Dxe/Setup/processor.c
@@ -0,0 +1,46 @@
+/** @file
+Platform CPU Data
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+
+#include "CommonHeader.h"
+
+#include "SetupPlatform.h"
+
+
+#define NUMBER_OF_PACKAGES 1
+
+CHAR16 *SocketNames[NUMBER_OF_PACKAGES];
+CHAR16 *AssetTags[NUMBER_OF_PACKAGES];
+
+CHAR16 EmptyString[] = L" ";
+CHAR16 SocketString[] = L"LGA775";
+
+VOID
+ProducePlatformCpuData (
+ VOID
+ )
+{
+ UINTN Index;
+
+ for (Index = 0; Index < NUMBER_OF_PACKAGES; Index++) {
+
+ //
+ // The String Package of a module is registered together with all IFR packages.
+ // So we just arbitrarily pick a package GUID that is always installed to get the string.
+ //
+ AssetTags[Index] = EmptyString;
+ SocketNames[Index] = SocketString;
+ }
+}
diff --git a/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/CommonHeader.h b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/CommonHeader.h
new file mode 100644
index 0000000000..b206fcefa9
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/CommonHeader.h
@@ -0,0 +1,40 @@
+/** @file
+Common header file shared by all source files.
+
+This file includes package header files, library classes and protocol, PPI & GUID definitions.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+
+#ifndef __COMMON_HEADER_H_
+#define __COMMON_HEADER_H_
+
+
+
+#include <FrameworkDxe.h>
+#include <IndustryStandard/SmBios.h>
+#include <Protocol/Smbios.h>
+#include <Guid/MdeModuleHii.h>
+#include <Guid/DataHubRecords.h>
+
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/HiiLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiLib.h>
+
+extern EFI_HII_HANDLE gHiiHandle;
+#endif
diff --git a/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBaseBoardManufacturer.uni b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBaseBoardManufacturer.uni
new file mode 100644
index 0000000000..b708b98c6c
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBaseBoardManufacturer.uni
@@ -0,0 +1,25 @@
+// /** @file
+// System Manufacturer Information
+//
+// Copyright (c) 2013-2015 Intel Corporation.
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+//
+// **/
+
+/=#
+
+#string STR_MISC_BASE_BOARD_MANUFACTURER #language en-US "Intel Corp."
+#string STR_MISC_BASE_BOARD_PRODUCT_NAME #language en-US "QUARK"
+#string STR_MISC_BASE_BOARD_VERSION #language en-US "FAB-D"
+#string STR_MISC_BASE_BOARD_SERIAL_NUMBER #language en-US "XXXXXXXXXXXX"
+#string STR_MISC_BASE_BOARD_ASSET_TAG #language en-US "Base Board Asset Tag"
+#string STR_MISC_BASE_BOARD_CHASSIS_LOCATION #language en-US "Part Component"
+
diff --git a/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBaseBoardManufacturerData.c b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBaseBoardManufacturerData.c
new file mode 100644
index 0000000000..36cdec361f
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBaseBoardManufacturerData.c
@@ -0,0 +1,51 @@
+/** @file
+Type 2: Base Board Information.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+
+#include "CommonHeader.h"
+#include "SmbiosMisc.h"
+
+//
+// Static (possibly build generated) Bios Vendor data.
+//
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_BASE_BOARD_MANUFACTURER_DATA, MiscBaseBoardManufacturer)
+= {
+ STRING_TOKEN(STR_MISC_BASE_BOARD_MANUFACTURER),
+ STRING_TOKEN(STR_MISC_BASE_BOARD_PRODUCT_NAME),
+ STRING_TOKEN(STR_MISC_BASE_BOARD_VERSION),
+ STRING_TOKEN(STR_MISC_BASE_BOARD_SERIAL_NUMBER),
+ STRING_TOKEN(STR_MISC_BASE_BOARD_ASSET_TAG),
+ STRING_TOKEN(STR_MISC_BASE_BOARD_CHASSIS_LOCATION),
+ { // BaseBoardFeatureFlags
+ 1, // Motherboard
+ 0, // RequiresDaughterCard
+ 0, // Removable
+ 1, // Replaceable,
+ 0, // HotSwappable
+ 0, // Reserved
+ },
+ EfiBaseBoardTypeUnknown, // BaseBoardType
+ { // BaseBoardChassisLink
+ EFI_MISC_SUBCLASS_GUID, // ProducerName
+ 1, // Instance
+ 1, // SubInstance
+ },
+ 0, // BaseBoardNumberLinks
+ { // LinkN
+ EFI_MISC_SUBCLASS_GUID, // ProducerName
+ 1, // Instance
+ 1, // SubInstance
+ },
+};
diff --git a/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBaseBoardManufacturerFunction.c b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBaseBoardManufacturerFunction.c
new file mode 100644
index 0000000000..5435e2e457
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBaseBoardManufacturerFunction.c
@@ -0,0 +1,187 @@
+/** @file
+Base Board Information boot time changes.
+Misc. subclass type 4.
+SMBIOS type 2.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+
+#include "CommonHeader.h"
+#include "SmbiosMisc.h"
+
+/**
+ This function makes boot time changes to the contents of the
+ MiscBaseBoardManufacturer (Type 2).
+
+ @param RecordData Pointer to copy of RecordData from the Data Table.
+
+ @retval EFI_SUCCESS All parameters were valid.
+ @retval EFI_UNSUPPORTED Unexpected RecordType value.
+ @retval EFI_INVALID_PARAMETER Invalid parameter was found.
+
+**/
+MISC_SMBIOS_TABLE_FUNCTION(MiscBaseBoardManufacturer)
+{
+ CHAR8 *OptionalStrStart;
+ UINTN ManuStrLen;
+ UINTN ProductStrLen;
+ UINTN VerStrLen;
+ UINTN AssertTagStrLen;
+ UINTN SerialNumStrLen;
+ UINTN ChassisStrLen;
+ EFI_STATUS Status;
+ EFI_STRING Manufacturer;
+ EFI_STRING Product;
+ EFI_STRING Version;
+ EFI_STRING SerialNumber;
+ EFI_STRING AssertTag;
+ EFI_STRING Chassis;
+ STRING_REF TokenToGet;
+ STRING_REF TokenToUpdate;
+ EFI_SMBIOS_HANDLE SmbiosHandle;
+ SMBIOS_TABLE_TYPE2 *SmbiosRecord;
+ EFI_MISC_BASE_BOARD_MANUFACTURER *ForType2InputData;
+ UINTN TypeStringSize;
+ CHAR16 TypeString[SMBIOS_STRING_MAX_LENGTH];
+
+ ForType2InputData = (EFI_MISC_BASE_BOARD_MANUFACTURER *)RecordData;
+
+ //
+ // First check for invalid parameters.
+ //
+ if (RecordData == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ TokenToGet = STRING_TOKEN (STR_MISC_BASE_BOARD_MANUFACTURER);
+ Manufacturer = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL);
+ ManuStrLen = StrLen(Manufacturer);
+ if (ManuStrLen > SMBIOS_STRING_MAX_LENGTH) {
+ return EFI_UNSUPPORTED;
+ }
+
+ StrCpy (TypeString, L"");
+ TypeStringSize = PcdGetSize (PcdPlatformTypeName);
+ if (TypeStringSize > 0 && TypeStringSize <= sizeof (TypeString)) {
+ CopyMem (TypeString, PcdGetPtr (PcdPlatformTypeName), TypeStringSize);
+ }
+ if (StrLen (TypeString) == 0) {
+ StrCpy (TypeString, L"Unknown");
+ }
+ TokenToUpdate = STRING_TOKEN (STR_MISC_BASE_BOARD_PRODUCT_NAME);
+ HiiSetString (mHiiHandle, TokenToUpdate, TypeString, NULL);
+
+ TokenToGet = STRING_TOKEN (STR_MISC_BASE_BOARD_PRODUCT_NAME);
+ Product = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL);
+ ProductStrLen = StrLen(TypeString);
+ if (ProductStrLen > SMBIOS_STRING_MAX_LENGTH) {
+ return EFI_UNSUPPORTED;
+ }
+
+ TokenToGet = STRING_TOKEN (STR_MISC_BASE_BOARD_VERSION);
+ Version = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL);
+ VerStrLen = StrLen(Version);
+ if (VerStrLen > SMBIOS_STRING_MAX_LENGTH) {
+ return EFI_UNSUPPORTED;
+ }
+
+ TokenToGet = STRING_TOKEN (STR_MISC_BASE_BOARD_SERIAL_NUMBER);
+ SerialNumber = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL);
+ SerialNumStrLen = StrLen(SerialNumber);
+ if (SerialNumStrLen > SMBIOS_STRING_MAX_LENGTH) {
+ return EFI_UNSUPPORTED;
+ }
+
+ TokenToGet = STRING_TOKEN (STR_MISC_BASE_BOARD_ASSET_TAG);
+ AssertTag = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL);
+ AssertTagStrLen = StrLen(AssertTag);
+ if (AssertTagStrLen > SMBIOS_STRING_MAX_LENGTH) {
+ return EFI_UNSUPPORTED;
+ }
+
+ TokenToGet = STRING_TOKEN (STR_MISC_BASE_BOARD_CHASSIS_LOCATION);
+ Chassis = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL);
+ ChassisStrLen = StrLen(Chassis);
+ if (ChassisStrLen > SMBIOS_STRING_MAX_LENGTH) {
+ return EFI_UNSUPPORTED;
+ }
+
+
+ //
+ // Two zeros following the last string.
+ //
+ SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE3) + ManuStrLen + 1 + ProductStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1 + AssertTagStrLen + 1 + ChassisStrLen +1 + 1);
+ ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE3) + ManuStrLen + 1 + ProductStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1 + AssertTagStrLen + 1 + ChassisStrLen +1 + 1);
+
+ SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_BASEBOARD_INFORMATION;
+ SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE2);
+ //
+ // Make handle chosen by smbios protocol.add automatically.
+ //
+ SmbiosRecord->Hdr.Handle = 0;
+ //
+ // Manu will be the 1st optional string following the formatted structure.
+ //
+ SmbiosRecord->Manufacturer = 1;
+ //
+ // ProductName will be the 2st optional string following the formatted structure.
+ //
+ SmbiosRecord->ProductName = 2;
+ //
+ // Version will be the 3rd optional string following the formatted structure.
+ //
+ SmbiosRecord->Version = 3;
+ //
+ // SerialNumber will be the 4th optional string following the formatted structure.
+ //
+ SmbiosRecord->SerialNumber = 4;
+ //
+ // AssertTag will be the 5th optional string following the formatted structure.
+ //
+ SmbiosRecord->AssetTag = 5;
+
+ //
+ // LocationInChassis will be the 6th optional string following the formatted structure.
+ //
+ SmbiosRecord->LocationInChassis = 6;
+ SmbiosRecord->FeatureFlag = (*(BASE_BOARD_FEATURE_FLAGS*)&(ForType2InputData->BaseBoardFeatureFlags));
+ SmbiosRecord->ChassisHandle = 0;
+ SmbiosRecord->BoardType = (UINT8)ForType2InputData->BaseBoardType;
+ SmbiosRecord->NumberOfContainedObjectHandles = 0;
+
+ OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
+ //
+ // Since we fill NumberOfContainedObjectHandles = 0 for simple, just after this filed to fill string
+ //
+ //OptionalStrStart -= 2;
+ UnicodeStrToAsciiStr(Manufacturer, OptionalStrStart);
+ UnicodeStrToAsciiStr(Product, OptionalStrStart + ManuStrLen + 1);
+ UnicodeStrToAsciiStr(Version, OptionalStrStart + ManuStrLen + 1 + ProductStrLen + 1);
+ UnicodeStrToAsciiStr(SerialNumber, OptionalStrStart + ManuStrLen + 1 + ProductStrLen + 1 + VerStrLen + 1);
+ UnicodeStrToAsciiStr(AssertTag, OptionalStrStart + ManuStrLen + 1 + ProductStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1);
+ UnicodeStrToAsciiStr(Chassis, OptionalStrStart + ManuStrLen + 1 + ProductStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1 + AssertTagStrLen + 1);
+
+ //
+ // Now we have got the full smbios record, call smbios protocol to add this record.
+ //
+ SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+ Status = Smbios-> Add(
+ Smbios,
+ NULL,
+ &SmbiosHandle,
+ (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
+ );
+
+ FreePool(SmbiosRecord);
+ return Status;
+}
diff --git a/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBiosVendor.uni b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBiosVendor.uni
new file mode 100644
index 0000000000..896dd21590
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBiosVendor.uni
@@ -0,0 +1,24 @@
+// /** @file
+// BIOS vendor information.
+// Misc. subclass type 2.
+// SMBIOS type 0.
+//
+// Copyright (c) 2013-2015 Intel Corporation.
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+//
+// **/
+
+
+/=#
+
+#string STR_MISC_BIOS_VENDOR #language en-US "Intel Corp."
+#string STR_MISC_BIOS_VERSION #language en-US "BIOS Version"
+#string STR_MISC_BIOS_RELEASE_DATE #language en-US "11/03/2015"
diff --git a/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBiosVendorData.c b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBiosVendorData.c
new file mode 100644
index 0000000000..a1213dd1d2
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBiosVendorData.c
@@ -0,0 +1,98 @@
+/** @file
+BIOS vendor information static data.
+Misc. subclass type 2.
+SMBIOS type 0.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+
+**/
+
+
+#include "CommonHeader.h"
+
+#include "SmbiosMisc.h"
+
+
+//
+// Static (possibly build generated) Bios Vendor data.
+//
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_BIOS_VENDOR, MiscBiosVendor) = {
+ STRING_TOKEN (STR_MISC_BIOS_VENDOR), // BiosVendor
+ STRING_TOKEN (STR_MISC_BIOS_VERSION), // BiosVersion
+ STRING_TOKEN (STR_MISC_BIOS_RELEASE_DATE), // BiosReleaseDate
+ 0xE0000, // BiosStartingAddress
+ { // BiosPhysicalDeviceSize
+ 2, // Value
+ 20, // Exponent
+ },
+ { // BiosCharacteristics1
+ 0, // Reserved1 :2
+ 0, // Unknown :1
+ 0, // BiosCharacteristicsNotSupported :1
+ 0, // IsaIsSupported :1
+ 0, // McaIsSupported :1
+
+ 0, // EisaIsSupported :1
+ 1, // PciIsSupported :1
+ 0, // PcmciaIsSupported :1
+ 0, // PlugAndPlayIsSupported :1
+ 0, // ApmIsSupported :1
+
+ 1, // BiosIsUpgradable :1
+ 1, // BiosShadowingAllowed :1
+ 0, // VlVesaIsSupported :1
+ 0, // EscdSupportIsAvailable :1
+ 1, // BootFromCdIsSupported :1
+
+ 1, // SelectableBootIsSupported :1
+ 0, // RomBiosIsSocketed :1
+ 0, // BootFromPcmciaIsSupported :1
+ 1, // EDDSpecificationIsSupported :1
+ 0, // JapaneseNecFloppyIsSupported :1
+
+ 0, // JapaneseToshibaFloppyIsSupported :1
+ 0, // Floppy525_360IsSupported :1
+ 0, // Floppy525_12IsSupported :1
+ 0, // Floppy35_720IsSupported :1
+ 0, // Floppy35_288IsSupported :1
+
+ 1, // PrintScreenIsSupported :1
+ 1, // Keyboard8042IsSupported :1
+ 1, // SerialIsSupported :1
+ 1, // PrinterIsSupported :1
+ 1, // CgaMonoIsSupported :1
+
+ 0, // NecPc98 :1
+ 1, // AcpiIsSupported :1
+ 1, // UsbLegacyIsSupported :1
+ 0, // AgpIsSupported :1
+ 0, // I20BootIsSupported :1
+
+ 0, // Ls120BootIsSupported :1
+ 0, // AtapiZipDriveBootIsSupported :1
+ 0, // Boot1394IsSupported :1
+ 0, // SmartBatteryIsSupported :1
+ 1, // BiosBootSpecIsSupported :1
+
+ 1, // FunctionKeyNetworkBootIsSupported :1
+ 0 // Reserved :22
+ },
+ { // BiosCharacteristics2
+ 0, // BiosReserved :16
+ 0, // SystemReserved :16
+ 0 // Reserved :32
+ },
+ 0x1, // System BIOS Major Release
+ 0x0, // System BIOS Minor Release
+ 0xFF, // Embedded controller firmware major Release
+ 0xFF, // Embedded controller firmware minor Release
+};
diff --git a/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBiosVendorFunction.c b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBiosVendorFunction.c
new file mode 100644
index 0000000000..e3ab7ff242
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBiosVendorFunction.c
@@ -0,0 +1,228 @@
+/** @file
+BIOS vendor information boot time changes.
+Misc. subclass type 2.
+SMBIOS type 0.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+
+**/
+
+
+#include "CommonHeader.h"
+
+#include "SmbiosMisc.h"
+
+/**
+ This function returns the value & exponent to Base2 for a given
+ Hex value. This is used to calculate the BiosPhysicalDeviceSize.
+
+ @param Value The hex value which is to be converted into value-exponent form
+ @param Exponent The exponent out of the conversion
+
+ @retval EFI_SUCCESS All parameters were valid and *Value & *Exponent have been set.
+ @retval EFI_INVALID_PARAMETER Invalid parameter was found.
+
+**/
+EFI_STATUS
+GetValueExponentBase2(
+ IN OUT UINTN *Value,
+ OUT UINTN *Exponent
+ )
+{
+ if ((Value == NULL) || (Exponent == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ while ((*Value % 2) == 0) {
+ *Value=*Value/2;
+ (*Exponent)++;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Field Filling Function. Transform an EFI_EXP_BASE2_DATA to a byte, with '64k'
+ as the unit.
+
+ @param Base2Data Pointer to Base2_Data
+
+ @retval EFI_SUCCESS Transform successfully.
+ @retval EFI_INVALID_PARAMETER Invalid parameter was found.
+
+**/
+UINT16
+Base2ToByteWith64KUnit (
+ IN EFI_EXP_BASE2_DATA *Base2Data
+ )
+{
+ UINT16 Value;
+ UINT16 Exponent;
+
+ Value = Base2Data->Value;
+ Exponent = Base2Data->Exponent;
+ Exponent -= 16;
+ Value <<= Exponent;
+
+ return Value;
+}
+
+
+/**
+ This function makes boot time changes to the contents of the
+ MiscBiosVendor (Type 0).
+
+ @param RecordData Pointer to copy of RecordData from the Data Table.
+
+ @retval EFI_SUCCESS All parameters were valid.
+ @retval EFI_UNSUPPORTED Unexpected RecordType value.
+ @retval EFI_INVALID_PARAMETER Invalid parameter was found.
+
+**/
+MISC_SMBIOS_TABLE_FUNCTION(MiscBiosVendor)
+{
+ CHAR8 *OptionalStrStart;
+ UINTN VendorStrLen;
+ UINTN VerStrLen;
+ UINTN DateStrLen;
+ UINTN BiosPhysicalSizeHexValue;
+ UINTN BiosPhysicalSizeExponent;
+ CHAR16 Version[SMBIOS_STRING_MAX_LENGTH];
+ CHAR16 Vendor[SMBIOS_STRING_MAX_LENGTH];
+ CHAR16 ReleaseDate[SMBIOS_STRING_MAX_LENGTH];
+ EFI_STRING VersionPtr;
+ EFI_STRING VendorPtr;
+ EFI_STRING ReleaseDatePtr;
+ EFI_STATUS Status;
+ STRING_REF TokenToGet;
+ STRING_REF TokenToUpdate;
+ SMBIOS_TABLE_TYPE0 *SmbiosRecord;
+ EFI_SMBIOS_HANDLE SmbiosHandle;
+ EFI_MISC_BIOS_VENDOR *ForType0InputData;
+
+ BiosPhysicalSizeHexValue = 0x0;
+ BiosPhysicalSizeExponent = 0x0;
+ ForType0InputData = (EFI_MISC_BIOS_VENDOR *)RecordData;
+
+ //
+ // First check for invalid parameters.
+ //
+ if (RecordData == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // Now update the BiosPhysicalSize
+ //
+ BiosPhysicalSizeHexValue = PcdGet32 (PcdFlashAreaSize);
+ Status= GetValueExponentBase2 (
+ &BiosPhysicalSizeHexValue,
+ &BiosPhysicalSizeExponent
+ );
+ if(Status == EFI_SUCCESS){
+ ForType0InputData->BiosPhysicalDeviceSize.Value = (UINT16)BiosPhysicalSizeHexValue;
+ ForType0InputData->BiosPhysicalDeviceSize.Exponent = (UINT16)BiosPhysicalSizeExponent;
+ }
+ //
+ // Update strings from PCD
+ //
+ AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr (PcdSMBIOSBiosVendor), Vendor);
+ if (StrLen (Vendor) > 0) {
+ TokenToUpdate = STRING_TOKEN (STR_MISC_BIOS_VENDOR);
+ HiiSetString (mHiiHandle, TokenToUpdate, Vendor, NULL);
+ }
+ TokenToGet = STRING_TOKEN (STR_MISC_BIOS_VENDOR);
+ VendorPtr = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL);
+ VendorStrLen = StrLen(VendorPtr);
+ if (VendorStrLen > SMBIOS_STRING_MAX_LENGTH) {
+ return EFI_UNSUPPORTED;
+ }
+
+ UnicodeSPrint (Version, sizeof (Version), L"0x%08x", PcdGet32 (PcdFirmwareRevision));
+ if (StrLen (Version) > 0) {
+ TokenToUpdate = STRING_TOKEN (STR_MISC_BIOS_VERSION);
+ HiiSetString (mHiiHandle, TokenToUpdate, Version, NULL);
+ }
+ TokenToGet = STRING_TOKEN (STR_MISC_BIOS_VERSION);
+ VersionPtr = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL);
+ VerStrLen = StrLen(VersionPtr);
+ if (VerStrLen > SMBIOS_STRING_MAX_LENGTH) {
+ return EFI_UNSUPPORTED;
+ }
+
+ AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr (PcdSMBIOSBiosReleaseDate), ReleaseDate);
+ if (StrLen (ReleaseDate) > 0) {
+ TokenToUpdate = STRING_TOKEN (STR_MISC_BIOS_RELEASE_DATE);
+ HiiSetString (mHiiHandle, TokenToUpdate, ReleaseDate, NULL);
+ }
+ TokenToGet = STRING_TOKEN (STR_MISC_BIOS_RELEASE_DATE);
+ ReleaseDatePtr = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL);
+ DateStrLen = StrLen(ReleaseDatePtr);
+ if (DateStrLen > SMBIOS_STRING_MAX_LENGTH) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Two zeros following the last string.
+ //
+ SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE0) + VendorStrLen + 1 + VerStrLen + 1 + DateStrLen + 1 + 1);
+ ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE0) + VendorStrLen + 1 + VerStrLen + 1 + DateStrLen + 1 + 1);
+
+ SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_BIOS_INFORMATION;
+ SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE0);
+ //
+ // Make handle chosen by smbios protocol.add automatically.
+ //
+ SmbiosRecord->Hdr.Handle = 0;
+ //
+ // Vendor will be the 1st optional string following the formatted structure.
+ //
+ SmbiosRecord->Vendor = 1;
+ //
+ // Version will be the 2nd optional string following the formatted structure.
+ //
+ SmbiosRecord->BiosVersion = 2;
+ SmbiosRecord->BiosSegment = PcdGet16 (PcdSMBIOSBiosStartAddress);
+ //
+ // ReleaseDate will be the 3rd optional string following the formatted structure.
+ //
+ SmbiosRecord->BiosReleaseDate = 3;
+ SmbiosRecord->BiosSize = (UINT8)(Base2ToByteWith64KUnit(&ForType0InputData->BiosPhysicalDeviceSize) - 1);
+ *(UINT64 *)&SmbiosRecord->BiosCharacteristics = PcdGet64 (PcdSMBIOSBiosChar);
+ //
+ // CharacterExtensionBytes also store in ForType0InputData->BiosCharacteristics1 later two bytes to save size.
+ //
+ SmbiosRecord->BIOSCharacteristicsExtensionBytes[0] = PcdGet8 (PcdSMBIOSBiosCharEx1);
+ SmbiosRecord->BIOSCharacteristicsExtensionBytes[1] = PcdGet8 (PcdSMBIOSBiosCharEx2);
+
+ SmbiosRecord->SystemBiosMajorRelease = ForType0InputData->BiosMajorRelease;
+ SmbiosRecord->SystemBiosMinorRelease = ForType0InputData->BiosMinorRelease;
+ SmbiosRecord->EmbeddedControllerFirmwareMajorRelease = ForType0InputData->BiosEmbeddedFirmwareMajorRelease;
+ SmbiosRecord->EmbeddedControllerFirmwareMinorRelease = ForType0InputData->BiosEmbeddedFirmwareMinorRelease;
+
+ OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
+ UnicodeStrToAsciiStr(VendorPtr, OptionalStrStart);
+ UnicodeStrToAsciiStr(VersionPtr, OptionalStrStart + VendorStrLen + 1);
+ UnicodeStrToAsciiStr(ReleaseDatePtr, OptionalStrStart + VendorStrLen + 1 + VerStrLen + 1);
+ //
+ // Now we have got the full smbios record, call smbios protocol to add this record.
+ //
+ SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+ Status = Smbios-> Add(
+ Smbios,
+ NULL,
+ &SmbiosHandle,
+ (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
+ );
+
+ FreePool(SmbiosRecord);
+ return Status;
+}
diff --git a/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBootInformationData.c b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBootInformationData.c
new file mode 100644
index 0000000000..b074cec432
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBootInformationData.c
@@ -0,0 +1,30 @@
+/** @file
+This driver parses the mMiscSubclassDataTable structure and reports
+any generated data to the DataHub.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+
+**/
+
+
+#include "CommonHeader.h"
+
+#include "SmbiosMisc.h"
+
+
+//
+// Static (possibly build generated) Bios Vendor data. SMBIOS TYPE 32
+//
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_BOOT_INFORMATION_STATUS, MiscBootInfoStatus) = {
+ EfiBootInformationStatusNoError, // BootInformationStatus
+ {0} // BootInformationData
+};
diff --git a/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBootInformationFunction.c b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBootInformationFunction.c
new file mode 100644
index 0000000000..976912ccc8
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscBootInformationFunction.c
@@ -0,0 +1,77 @@
+/** @file
+boot information boot time changes.
+SMBIOS type 32.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+
+**/
+
+
+#include "CommonHeader.h"
+#include "SmbiosMisc.h"
+
+
+/**
+ This function makes boot time changes to the contents of the
+ MiscBootInformation (Type 32).
+
+ @param RecordData Pointer to copy of RecordData from the Data Table.
+
+ @retval EFI_SUCCESS All parameters were valid.
+ @retval EFI_UNSUPPORTED Unexpected RecordType value.
+ @retval EFI_INVALID_PARAMETER Invalid parameter was found.
+
+**/
+
+MISC_SMBIOS_TABLE_FUNCTION(MiscBootInfoStatus)
+{
+ EFI_STATUS Status;
+ EFI_SMBIOS_HANDLE SmbiosHandle;
+ SMBIOS_TABLE_TYPE32 *SmbiosRecord;
+ EFI_MISC_BOOT_INFORMATION_STATUS* ForType32InputData;
+
+ ForType32InputData = (EFI_MISC_BOOT_INFORMATION_STATUS *)RecordData;
+
+ //
+ // First check for invalid parameters.
+ //
+ if (RecordData == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Two zeros following the last string.
+ //
+ SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE32) + 1 + 1);
+ ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE32) + 1 + 1);
+
+ SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_SYSTEM_BOOT_INFORMATION;
+ SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE32);
+ //
+ // Make handle chosen by smbios protocol.add automatically.
+ //
+ SmbiosRecord->Hdr.Handle = 0;
+ SmbiosRecord->BootStatus = (UINT8)ForType32InputData->BootInformationStatus;
+
+ //
+ // Now we have got the full smbios record, call smbios protocol to add this record.
+ //
+ SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+ Status = Smbios-> Add(
+ Smbios,
+ NULL,
+ &SmbiosHandle,
+ (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
+ );
+ FreePool(SmbiosRecord);
+ return Status;
+}
diff --git a/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscChassisManufacturer.uni b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscChassisManufacturer.uni
new file mode 100644
index 0000000000..7499f3e396
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscChassisManufacturer.uni
@@ -0,0 +1,23 @@
+// /** @file
+// Miscellaneous chassis manufacturer information
+//
+// Copyright (c) 2013-2015 Intel Corporation.
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+//
+// **/
+
+
+/=#
+
+#string STR_MISC_CHASSIS_MANUFACTURER #language en-US "Chassis Manufacturer"
+#string STR_MISC_CHASSIS_VERSION #language en-US "Chassis Version"
+#string STR_MISC_CHASSIS_SERIAL_NUMBER #language en-US "Chassis Serial Number"
+#string STR_MISC_CHASSIS_ASSET_TAG #language en-US "Chassis Asset Tag"
diff --git a/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscChassisManufacturerData.c b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscChassisManufacturerData.c
new file mode 100644
index 0000000000..febfcd74a2
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscChassisManufacturerData.c
@@ -0,0 +1,42 @@
+/** @file
+This driver parses the mMiscSubclassDataTable structure and reports
+any generated data to the DataHub.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+
+**/
+
+
+#include "CommonHeader.h"
+
+#include "SmbiosMisc.h"
+
+
+//
+// Static (possibly build generated) Chassis Manufacturer data.
+//
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_CHASSIS_MANUFACTURER, MiscChassisManufacturer) = {
+ STRING_TOKEN(STR_MISC_CHASSIS_MANUFACTURER), // ChassisManufactrurer
+ STRING_TOKEN(STR_MISC_CHASSIS_VERSION), // ChassisVersion
+ STRING_TOKEN(STR_MISC_CHASSIS_SERIAL_NUMBER), // ChassisSerialNumber
+ STRING_TOKEN(STR_MISC_CHASSIS_ASSET_TAG), // ChassisAssetTag
+ { // ChassisTypeStatus
+ EfiMiscChassisTypeDeskTop, // ChassisType
+ 0, // ChassisLockPresent
+ 0 // Reserved
+ },
+ EfiChassisStateSafe, // ChassisBootupState
+ EfiChassisStateSafe, // ChassisPowerSupplyState
+ EfiChassisStateOther, // ChassisThermalState
+ EfiChassisSecurityStatusOther, // ChassisSecurityState
+ 0 // ChassisOemDefined
+};
diff --git a/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscChassisManufacturerFunction.c b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscChassisManufacturerFunction.c
new file mode 100644
index 0000000000..ea0cf6121b
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscChassisManufacturerFunction.c
@@ -0,0 +1,174 @@
+/** @file
+Chassis manufacturer information boot time changes.
+SMBIOS type 3.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+
+**/
+
+
+#include "CommonHeader.h"
+
+#include "SmbiosMisc.h"
+
+/**
+ This function makes boot time changes to the contents of the
+ MiscChassisManufacturer (Type 3).
+
+ @param RecordData Pointer to copy of RecordData from the Data Table.
+
+ @retval EFI_SUCCESS All parameters were valid.
+ @retval EFI_UNSUPPORTED Unexpected RecordType value.
+ @retval EFI_INVALID_PARAMETER Invalid parameter was found.
+
+**/
+MISC_SMBIOS_TABLE_FUNCTION(MiscChassisManufacturer)
+{
+ CHAR8 *OptionalStrStart;
+ UINTN ManuStrLen;
+ UINTN VerStrLen;
+ UINTN AssertTagStrLen;
+ UINTN SerialNumStrLen;
+ EFI_STATUS Status;
+ CHAR16 Manufacturer[SMBIOS_STRING_MAX_LENGTH];
+ CHAR16 Version[SMBIOS_STRING_MAX_LENGTH];
+ CHAR16 SerialNumber[SMBIOS_STRING_MAX_LENGTH];
+ CHAR16 AssertTag[SMBIOS_STRING_MAX_LENGTH];
+ EFI_STRING ManufacturerPtr;
+ EFI_STRING VersionPtr;
+ EFI_STRING SerialNumberPtr;
+ EFI_STRING AssertTagPtr;
+ STRING_REF TokenToGet;
+ STRING_REF TokenToUpdate;
+ EFI_SMBIOS_HANDLE SmbiosHandle;
+ SMBIOS_TABLE_TYPE3 *SmbiosRecord;
+ EFI_MISC_CHASSIS_MANUFACTURER *ForType3InputData;
+
+ ForType3InputData = (EFI_MISC_CHASSIS_MANUFACTURER *)RecordData;
+
+ //
+ // First check for invalid parameters.
+ //
+ if (RecordData == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Update strings from PCD
+ //
+ AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSChassisManufacturer), Manufacturer);
+ if (StrLen (Manufacturer) > 0) {
+ TokenToUpdate = STRING_TOKEN (STR_MISC_CHASSIS_MANUFACTURER);
+ HiiSetString (mHiiHandle, TokenToUpdate, Manufacturer, NULL);
+ }
+ TokenToGet = STRING_TOKEN (STR_MISC_CHASSIS_MANUFACTURER);
+ ManufacturerPtr = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL);
+ ManuStrLen = StrLen(ManufacturerPtr);
+ if (ManuStrLen > SMBIOS_STRING_MAX_LENGTH) {
+ return EFI_UNSUPPORTED;
+ }
+
+ AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSChassisVersion), Version);
+ if (StrLen (Version) > 0) {
+ TokenToUpdate = STRING_TOKEN (STR_MISC_CHASSIS_VERSION);
+ HiiSetString (mHiiHandle, TokenToUpdate, Version, NULL);
+ }
+ TokenToGet = STRING_TOKEN (STR_MISC_CHASSIS_VERSION);
+ VersionPtr = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL);
+ VerStrLen = StrLen(VersionPtr);
+ if (VerStrLen > SMBIOS_STRING_MAX_LENGTH) {
+ return EFI_UNSUPPORTED;
+ }
+
+ AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSChassisSerialNumber), SerialNumber);
+ if (StrLen (SerialNumber) > 0) {
+ TokenToUpdate = STRING_TOKEN (STR_MISC_CHASSIS_SERIAL_NUMBER);
+ HiiSetString (mHiiHandle, TokenToUpdate, SerialNumber, NULL);
+ }
+ TokenToGet = STRING_TOKEN (STR_MISC_CHASSIS_SERIAL_NUMBER);
+ SerialNumberPtr = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL);
+ SerialNumStrLen = StrLen(SerialNumberPtr);
+ if (SerialNumStrLen > SMBIOS_STRING_MAX_LENGTH) {
+ return EFI_UNSUPPORTED;
+ }
+
+ AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSChassisAssetTag), AssertTag);
+ if (StrLen (AssertTag) > 0) {
+ TokenToUpdate = STRING_TOKEN (STR_MISC_CHASSIS_ASSET_TAG);
+ HiiSetString (mHiiHandle, TokenToUpdate, AssertTag, NULL);
+ }
+ TokenToGet = STRING_TOKEN (STR_MISC_CHASSIS_ASSET_TAG);
+ AssertTagPtr = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL);
+ AssertTagStrLen = StrLen(AssertTagPtr);
+ if (AssertTagStrLen > SMBIOS_STRING_MAX_LENGTH) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Two zeros following the last string.
+ //
+ SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE3) + ManuStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1 + AssertTagStrLen + 1 + 1);
+ ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE3) + ManuStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1 + AssertTagStrLen + 1 + 1);
+
+ SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_SYSTEM_ENCLOSURE;
+ SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE3);
+ //
+ // Make handle chosen by smbios protocol.add automatically.
+ //
+ SmbiosRecord->Hdr.Handle = 0;
+ //
+ // Manu will be the 1st optional string following the formatted structure.
+ //
+ SmbiosRecord->Manufacturer = 1;
+ SmbiosRecord->Type = PcdGet8 (PcdSMBIOSChassisType);
+ //
+ // Version will be the 2nd optional string following the formatted structure.
+ //
+ SmbiosRecord->Version = 2;
+ //
+ // SerialNumber will be the 3rd optional string following the formatted structure.
+ //
+ SmbiosRecord->SerialNumber = 3;
+ //
+ // AssertTag will be the 4th optional string following the formatted structure.
+ //
+ SmbiosRecord->AssetTag = 4;
+ SmbiosRecord->BootupState = PcdGet8 (PcdSMBIOSChassisBootupState);
+ SmbiosRecord->PowerSupplyState = PcdGet8 (PcdSMBIOSChassisPowerSupplyState);
+ SmbiosRecord->ThermalState = (UINT8)ForType3InputData->ChassisThermalState;
+ SmbiosRecord->SecurityStatus = PcdGet8 (PcdSMBIOSChassisSecurityState);
+ *(UINT32 *)&SmbiosRecord->OemDefined = PcdGet32 (PcdSMBIOSChassisOemDefined);
+ SmbiosRecord->Height = PcdGet8 (PcdSMBIOSChassisHeight);
+ SmbiosRecord->NumberofPowerCords = PcdGet8 (PcdSMBIOSChassisNumberPowerCords);
+ SmbiosRecord->ContainedElementCount = PcdGet8 (PcdSMBIOSChassisElementCount);
+ SmbiosRecord->ContainedElementRecordLength = PcdGet8 (PcdSMBIOSChassisElementRecordLength);
+
+ OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
+ UnicodeStrToAsciiStr(ManufacturerPtr, OptionalStrStart);
+ UnicodeStrToAsciiStr(VersionPtr, OptionalStrStart + ManuStrLen + 1);
+ UnicodeStrToAsciiStr(SerialNumberPtr, OptionalStrStart + ManuStrLen + 1 + VerStrLen + 1);
+ UnicodeStrToAsciiStr(AssertTagPtr, OptionalStrStart + ManuStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1);
+
+ //
+ // Now we have got the full smbios record, call smbios protocol to add this record.
+ //
+ SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+ Status = Smbios-> Add(
+ Smbios,
+ NULL,
+ &SmbiosHandle,
+ (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
+ );
+
+ FreePool(SmbiosRecord);
+ return Status;
+}
diff --git a/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscDevicePath.h b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscDevicePath.h
new file mode 100644
index 0000000000..13588dc0a9
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscDevicePath.h
@@ -0,0 +1,48 @@
+/** @file
+Misc class required EFI Device Path definitions (Ports, slots &
+onboard devices)
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+
+**/
+
+#ifndef _MISC_DEVICE_PATH_H
+#define _MISC_DEVICE_PATH_H
+
+#pragma pack(1)
+
+//USB
+/* For reference:
+#define USB1_1_STR "ACPI(PNP0A03,0)/PCI(1D,0)."
+#define USB1_2_STR "ACPI(PNP0A03,0)/PCI(1D,1)."
+#define USB1_3_STR "ACPI(PNP0A03,0)/PCI(1D,2)."
+#define USB2_1_STR "ACPI(PNP0A03,0)/PCI(1D,7)."
+*/
+
+#define DP_ACPI { ACPI_DEVICE_PATH,\
+ ACPI_DP, (UINT8) (sizeof (ACPI_HID_DEVICE_PATH)),\
+ (UINT8) ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8), EISA_PNP_ID(0x0A03), 0 }
+#define DP_PCI( device,function) { HARDWARE_DEVICE_PATH,\
+ HW_PCI_DP, (UINT8) (sizeof (PCI_DEVICE_PATH)),\
+ (UINT8) ((sizeof (PCI_DEVICE_PATH)) >> 8), function, device }
+#define DP_END { END_DEVICE_PATH_TYPE, \
+ END_ENTIRE_DEVICE_PATH_SUBTYPE, {END_DEVICE_PATH_LENGTH, 0 }}
+
+#define DP_LPC(eisaid,function ){ ACPI_DEVICE_PATH, \
+ACPI_DP,(UINT8) (sizeof (ACPI_HID_DEVICE_PATH)),\
+(UINT8) ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8),EISA_PNP_ID(eisaid), function }
+
+
+#pragma pack()
+
+
+#endif
diff --git a/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscNumberOfInstallableLanguagesData.c b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscNumberOfInstallableLanguagesData.c
new file mode 100644
index 0000000000..93f8c5a979
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscNumberOfInstallableLanguagesData.c
@@ -0,0 +1,34 @@
+/** @file
+This driver parses the mSmbiosMiscDataTable structure and reports
+any generated data to SMBIOS.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+
+**/
+
+
+#include "CommonHeader.h"
+
+#include "SmbiosMisc.h"
+
+
+//
+// Static (possibly build generated) Bios Vendor data.
+//
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_NUMBER_OF_INSTALLABLE_LANGUAGES, NumberOfInstallableLanguages) = {
+ 2, // NumberOfInstallableLanguages
+ { // LanguageFlags
+ 0, // AbbreviatedLanguageFormat
+ 0 // Reserved
+ },
+ 1, // CurrentLanguageNumber
+};
diff --git a/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscNumberOfInstallableLanguagesFunction.c b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscNumberOfInstallableLanguagesFunction.c
new file mode 100644
index 0000000000..d17f5ea356
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscNumberOfInstallableLanguagesFunction.c
@@ -0,0 +1,248 @@
+/** @file
+This driver parses the mSmbiosMiscDataTable structure and reports
+any generated data.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+
+**/
+
+
+#include "CommonHeader.h"
+
+#include "SmbiosMisc.h"
+/*++
+ Check whether the language is supported for given HII handle
+
+ @param HiiHandle The HII package list handle.
+ @param Offset The offest of current lanague in the supported languages.
+ @param CurrentLang The language code.
+
+ @retval TRUE Supported.
+ @retval FALSE Not Supported.
+
+--*/
+BOOLEAN
+EFIAPI
+CurrentLanguageMatch (
+ IN EFI_HII_HANDLE HiiHandle,
+ OUT UINT16 *Offset,
+ OUT CHAR8 *CurrentLang
+ )
+{
+ CHAR8 *DefaultLang;
+ CHAR8 *BestLanguage;
+ CHAR8 *Languages;
+ CHAR8 *MatchLang;
+ CHAR8 *EndMatchLang;
+ UINTN CompareLength;
+ BOOLEAN LangMatch;
+
+ Languages = HiiGetSupportedLanguages (HiiHandle);
+ if (Languages == NULL) {
+ return FALSE;
+ }
+
+ LangMatch = FALSE;
+ CurrentLang = GetEfiGlobalVariable (L"PlatformLang");
+ DefaultLang = (CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLang);
+ BestLanguage = GetBestLanguage (
+ Languages,
+ FALSE,
+ (CurrentLang != NULL) ? CurrentLang : "",
+ DefaultLang,
+ NULL
+ );
+ if (BestLanguage != NULL) {
+ //
+ // Find the best matching RFC 4646 language, compute the offset.
+ //
+ LangMatch = TRUE;
+ CompareLength = AsciiStrLen (BestLanguage);
+ for (MatchLang = Languages, (*Offset) = 0; *MatchLang != '\0'; (*Offset)++) {
+ //
+ // Seek to the end of current match language.
+ //
+ for (EndMatchLang = MatchLang; *EndMatchLang != '\0' && *EndMatchLang != ';'; EndMatchLang++);
+
+ if ((EndMatchLang == MatchLang + CompareLength) && AsciiStrnCmp(MatchLang, BestLanguage, CompareLength) == 0) {
+ //
+ // Find the current best Language in the supported languages
+ //
+ break;
+ }
+ //
+ // best language match be in the supported language.
+ //
+ ASSERT (*EndMatchLang == ';');
+ MatchLang = EndMatchLang + 1;
+ }
+ FreePool (BestLanguage);
+ }
+
+ FreePool (Languages);
+ if (CurrentLang != NULL) {
+ FreePool (CurrentLang);
+ }
+ return LangMatch;
+}
+
+
+/**
+ Get next language from language code list (with separator ';').
+
+ @param LangCode Input: point to first language in the list. On
+ Otput: point to next language in the list, or
+ NULL if no more language in the list.
+ @param Lang The first language in the list.
+
+**/
+VOID
+EFIAPI
+GetNextLanguage (
+ IN OUT CHAR8 **LangCode,
+ OUT CHAR8 *Lang
+ )
+{
+ UINTN Index;
+ CHAR8 *StringPtr;
+
+ ASSERT (LangCode != NULL);
+ ASSERT (*LangCode != NULL);
+ ASSERT (Lang != NULL);
+
+ Index = 0;
+ StringPtr = *LangCode;
+ while (StringPtr[Index] != 0 && StringPtr[Index] != ';') {
+ Index++;
+ }
+
+ CopyMem (Lang, StringPtr, Index);
+ Lang[Index] = 0;
+
+ if (StringPtr[Index] == ';') {
+ Index++;
+ }
+ *LangCode = StringPtr + Index;
+}
+
+/**
+ This function returns the number of supported languages on HiiHandle.
+
+ @param HiiHandle The HII package list handle.
+
+ @retval The number of supported languages.
+
+**/
+UINT16
+EFIAPI
+GetSupportedLanguageNumber (
+ IN EFI_HII_HANDLE HiiHandle
+ )
+{
+ CHAR8 *Lang;
+ CHAR8 *Languages;
+ CHAR8 *LanguageString;
+ UINT16 LangNumber;
+
+ Languages = HiiGetSupportedLanguages (HiiHandle);
+ if (Languages == NULL) {
+ return 0;
+ }
+
+ LangNumber = 0;
+ Lang = AllocatePool (AsciiStrSize (Languages));
+ if (Lang != NULL) {
+ LanguageString = Languages;
+ while (*LanguageString != 0) {
+ GetNextLanguage (&LanguageString, Lang);
+ LangNumber++;
+ }
+ FreePool (Lang);
+ }
+ FreePool (Languages);
+ return LangNumber;
+}
+
+
+/**
+ This function makes boot time changes to the contents of the
+ MiscNumberOfInstallableLanguages (Type 13).
+
+ @param RecordData Pointer to copy of RecordData from the Data Table.
+
+ @retval EFI_SUCCESS All parameters were valid.
+ @retval EFI_UNSUPPORTED Unexpected RecordType value.
+ @retval EFI_INVALID_PARAMETER Invalid parameter was found.
+
+**/
+MISC_SMBIOS_TABLE_FUNCTION(NumberOfInstallableLanguages)
+{
+ UINTN LangStrLen;
+ CHAR8 CurrentLang[SMBIOS_STRING_MAX_LENGTH + 1];
+ CHAR8 *OptionalStrStart;
+ UINT16 Offset;
+ BOOLEAN LangMatch;
+ 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
+ //
+ LangMatch = FALSE;
+ ZeroMem(CurrentLang, SMBIOS_STRING_MAX_LENGTH + 1);
+ LangMatch = 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/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOemString.uni b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOemString.uni
new file mode 100644
index 0000000000..664e95917a
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOemString.uni
@@ -0,0 +1,18 @@
+// /** @file
+// Unicode string used for SMBIOS type 11 record (OEM string)
+//
+// Copyright (c) 2013-2015 Intel Corporation.
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+/=#
+
+#string STR_MISC_OEM_EN_US #language en-US "Intel SSG"
diff --git a/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOemStringData.c b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOemStringData.c
new file mode 100644
index 0000000000..aeff165c2c
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOemStringData.c
@@ -0,0 +1,26 @@
+/** @file
+This driver parses the mMiscSubclassDataTable structure and reports
+any generated data to smbios.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+
+#include "CommonHeader.h"
+
+#include "SmbiosMisc.h"
+
+//
+// Static (possibly build generated) OEM String data.
+//
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_OEM_STRING, MiscOemString)
+= { {STRING_TOKEN(STR_MISC_OEM_EN_US) }};
diff --git a/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOemStringFunction.c b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOemStringFunction.c
new file mode 100644
index 0000000000..e352000104
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOemStringFunction.c
@@ -0,0 +1,87 @@
+/** @file
+boot information boot time changes.
+SMBIOS type 11.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+
+#include "CommonHeader.h"
+#include "SmbiosMisc.h"
+
+/**
+ This function makes boot time changes to the contents of the
+ MiscOemString (Type 11).
+
+ @param RecordData Pointer to copy of RecordData from the Data Table.
+
+ @retval EFI_SUCCESS All parameters were valid.
+ @retval EFI_UNSUPPORTED Unexpected RecordType value.
+ @retval EFI_INVALID_PARAMETER Invalid parameter was found.
+
+**/
+MISC_SMBIOS_TABLE_FUNCTION(MiscOemString)
+{
+ UINTN OemStrLen;
+ CHAR8 *OptionalStrStart;
+ EFI_STATUS Status;
+ EFI_STRING OemStr;
+ STRING_REF TokenToGet;
+ EFI_SMBIOS_HANDLE SmbiosHandle;
+ SMBIOS_TABLE_TYPE11 *SmbiosRecord;
+ EFI_MISC_OEM_STRING *ForType11InputData;
+
+ ForType11InputData = (EFI_MISC_OEM_STRING *)RecordData;
+
+ //
+ // First check for invalid parameters.
+ //
+ if (RecordData == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ TokenToGet = STRING_TOKEN (STR_MISC_OEM_EN_US);
+ OemStr = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL);
+ OemStrLen = StrLen(OemStr);
+ if (OemStrLen > SMBIOS_STRING_MAX_LENGTH) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Two zeros following the last string.
+ //
+ SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE11) + OemStrLen + 1 + 1);
+ ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE11) + OemStrLen + 1 + 1);
+
+ SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_OEM_STRINGS;
+ SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE11);
+ //
+ // Make handle chosen by smbios protocol.add automatically.
+ //
+ SmbiosRecord->Hdr.Handle = 0;
+ SmbiosRecord->StringCount = 1;
+ OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
+ UnicodeStrToAsciiStr(OemStr, OptionalStrStart);
+
+ //
+ // Now we have got the full smbios record, call smbios protocol to add this record.
+ //
+ SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+ Status = Smbios-> Add(
+ Smbios,
+ NULL,
+ &SmbiosHandle,
+ (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
+ );
+ FreePool(SmbiosRecord);
+ return Status;
+}
diff --git a/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOnboardDevice.uni b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOnboardDevice.uni
new file mode 100644
index 0000000000..99204ee4ca
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOnboardDevice.uni
@@ -0,0 +1,24 @@
+// /** @file
+// Miscellaneous Onboard Device
+//
+// Copyright (c) 2013-2015 Intel Corporation.
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+//
+// MiscOnboardDevice.Vfr
+//
+// **/
+
+
+/=#
+
+#string STR_MISC_ONBOARD_DEVICE_VIDEO #language en-US "Intel(R) Extreme Graphics 3 Controller"
+#string STR_MISC_ONBOARD_DEVICE_NETWORK #language en-US "Gigabit Ethernet"
+#string STR_MISC_ONBOARD_DEVICE_AUDIO #language en-US "Intel(R) High Definition Audio Device"
diff --git a/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOnboardDeviceData.c b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOnboardDeviceData.c
new file mode 100644
index 0000000000..54b4012f9a
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOnboardDeviceData.c
@@ -0,0 +1,55 @@
+/** @file
+This driver parses the mMiscSubclassDataTable structure and reports
+any generated data to smbios.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+
+**/
+
+
+#include "CommonHeader.h"
+
+#include "SmbiosMisc.h"
+
+
+//
+// Static (possibly build generated) Bios Vendor data.
+//
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_ONBOARD_DEVICE, MiscOnboardDeviceVideo) = {
+ STRING_TOKEN(STR_MISC_ONBOARD_DEVICE_VIDEO), // OnBoardDeviceDescription
+ { // OnBoardDeviceStatus
+ EfiOnBoardDeviceTypeVideo, // DeviceType
+ 1, // DeviceEnabled
+ 0 // Reserved
+ },
+ {0} // OnBoardDevicePath
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_ONBOARD_DEVICE, MiscOnboardDeviceNetwork) = {
+ STRING_TOKEN(STR_MISC_ONBOARD_DEVICE_NETWORK), // OnBoardDeviceDescription
+ { // OnBoardDeviceStatus
+ EfiOnBoardDeviceTypeEthernet, // DeviceType
+ 1, // DeviceEnabled
+ 0 // Reserved
+ },
+ {0} // OnBoardDevicePath
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_ONBOARD_DEVICE, MiscOnboardDeviceAudio) = {
+ STRING_TOKEN(STR_MISC_ONBOARD_DEVICE_AUDIO), // OnBoardDeviceDescription
+ { // OnBoardDeviceStatus
+ EfiOnBoardDeviceTypeSound, // DeviceType
+ 1, // DeviceEnabled
+ 0 // Reserved
+ },
+ DP_END // OnBoardDevicePath
+};
diff --git a/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOnboardDeviceFunction.c b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOnboardDeviceFunction.c
new file mode 100644
index 0000000000..7331db7e2a
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscOnboardDeviceFunction.c
@@ -0,0 +1,111 @@
+/** @file
+Onboard device information boot time changes.
+SMBIOS type 10.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+
+**/
+
+
+#include "CommonHeader.h"
+
+#include "SmbiosMisc.h"
+
+
+/**
+ This function makes boot time changes to the contents of the
+ MiscOnboardDevice (Type 10).
+
+ @param RecordData Pointer to copy of RecordData from the Data Table.
+
+ @retval EFI_SUCCESS All parameters were valid.
+ @retval EFI_UNSUPPORTED Unexpected RecordType value.
+ @retval EFI_INVALID_PARAMETER Invalid parameter was found.
+
+**/
+MISC_SMBIOS_TABLE_FUNCTION(MiscOnboardDevice)
+{
+ CHAR8 *OptionalStrStart;
+ UINT8 StatusAndType;
+ UINTN DescriptionStrLen;
+ EFI_STRING DeviceDescription;
+ STRING_REF TokenToGet;
+ EFI_STATUS Status;
+ EFI_SMBIOS_HANDLE SmbiosHandle;
+ SMBIOS_TABLE_TYPE10 *SmbiosRecord;
+ EFI_MISC_ONBOARD_DEVICE *ForType10InputData;
+
+ ForType10InputData = (EFI_MISC_ONBOARD_DEVICE *)RecordData;
+ //
+ // First check for invalid parameters.
+ //
+ if (RecordData == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ TokenToGet = 0;
+ switch (ForType10InputData->OnBoardDeviceDescription) {
+ case STR_MISC_ONBOARD_DEVICE_VIDEO:
+ TokenToGet = STRING_TOKEN (STR_MISC_ONBOARD_DEVICE_VIDEO);
+ break;
+ case STR_MISC_ONBOARD_DEVICE_AUDIO:
+ TokenToGet = STRING_TOKEN (STR_MISC_ONBOARD_DEVICE_AUDIO);
+ break;
+ }
+
+ DeviceDescription = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL);
+ DescriptionStrLen = StrLen(DeviceDescription);
+ if (DescriptionStrLen > SMBIOS_STRING_MAX_LENGTH) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Two zeros following the last string.
+ //
+ SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE10) + DescriptionStrLen + 1 + 1);
+ ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE10) + DescriptionStrLen + 1 + 1);
+
+ SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_ONBOARD_DEVICE_INFORMATION;
+ SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE10);
+ //
+ // Make handle chosen by smbios protocol.add automatically.
+ //
+ SmbiosRecord->Hdr.Handle = 0;
+
+ //
+ // Status & Type: Bit 7 Devicen Status, Bits 6:0 Type of Device
+ //
+ StatusAndType = (UINT8) ForType10InputData->OnBoardDeviceStatus.DeviceType;
+ if (ForType10InputData->OnBoardDeviceStatus.DeviceEnabled != 0) {
+ StatusAndType |= 0x80;
+ } else {
+ StatusAndType &= 0x7F;
+ }
+
+ SmbiosRecord->Device[0].DeviceType = StatusAndType;
+ SmbiosRecord->Device[0].DescriptionString = 1;
+ OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
+ UnicodeStrToAsciiStr(DeviceDescription, OptionalStrStart);
+
+ //
+ // Now we have got the full smbios record, call smbios protocol to add this record.
+ //
+ SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+ Status = Smbios-> Add(
+ Smbios,
+ NULL,
+ &SmbiosHandle,
+ (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
+ );
+ FreePool(SmbiosRecord);
+ return Status;
+}
diff --git a/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscPortInternalConnectorDesignator.uni b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscPortInternalConnectorDesignator.uni
new file mode 100644
index 0000000000..e4414b964d
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscPortInternalConnectorDesignator.uni
@@ -0,0 +1,59 @@
+// /** @file
+// Miscellaneous Port Internal Connector Information
+//
+// Copyright (c) 2013-2015 Intel Corporation.
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+//
+// **/
+/=#
+
+#string STR_MISC_PORT1_INTERNAL_DESIGN #language en-US "P1ICD"
+#string STR_MISC_PORT1_EXTERNAL_DESIGN #language en-US "P1ECD"
+#string STR_MISC_PORT2_INTERNAL_DESIGN #language en-US "P2ICD"
+#string STR_MISC_PORT2_EXTERNAL_DESIGN #language en-US "P2ECD"
+#string STR_MISC_PORT3_INTERNAL_DESIGN #language en-US "P3ICD"
+#string STR_MISC_PORT3_EXTERNAL_DESIGN #language en-US "P3ECD"
+#string STR_MISC_PORT4_INTERNAL_DESIGN #language en-US "P4ICD"
+#string STR_MISC_PORT4_EXTERNAL_DESIGN #language en-US "P4ECD"
+#string STR_MISC_PORT5_INTERNAL_DESIGN #language en-US "P5ICD"
+#string STR_MISC_PORT5_EXTERNAL_DESIGN #language en-US "P5ECD"
+#string STR_MISC_PORT6_INTERNAL_DESIGN #language en-US "P6ICD"
+#string STR_MISC_PORT6_EXTERNAL_DESIGN #language en-US "P6ECD"
+#string STR_MISC_PORT7_INTERNAL_DESIGN #language en-US "P7ICD"
+#string STR_MISC_PORT7_EXTERNAL_DESIGN #language en-US "P7ECD"
+#string STR_MISC_PORT8_INTERNAL_DESIGN #language en-US "P8ICD"
+#string STR_MISC_PORT8_EXTERNAL_DESIGN #language en-US "P8ECD"
+#string STR_MISC_PORT9_INTERNAL_DESIGN #language en-US "P9ICD"
+#string STR_MISC_PORT9_EXTERNAL_DESIGN #language en-US "P9ECD"
+#string STR_MISC_PORT10_INTERNAL_DESIGN #language en-US "P10ICD"
+#string STR_MISC_PORT10_EXTERNAL_DESIGN #language en-US "P10ECD"
+#string STR_MISC_PORT11_INTERNAL_DESIGN #language en-US "P11ICD"
+#string STR_MISC_PORT11_EXTERNAL_DESIGN #language en-US "P11ECD"
+#string STR_MISC_PORT12_INTERNAL_DESIGN #language en-US "P12ICD"
+#string STR_MISC_PORT12_EXTERNAL_DESIGN #language en-US "P12ECD"
+#string STR_MISC_PORT13_INTERNAL_DESIGN #language en-US "P13ICD"
+#string STR_MISC_PORT13_EXTERNAL_DESIGN #language en-US "P13ECD"
+#string STR_MISC_PORT14_INTERNAL_DESIGN #language en-US "P14ICD"
+#string STR_MISC_PORT14_EXTERNAL_DESIGN #language en-US "P14ECD"
+#string STR_MISC_PORT15_INTERNAL_DESIGN #language en-US "P15ICD"
+#string STR_MISC_PORT15_EXTERNAL_DESIGN #language en-US "P15ECD"
+#string STR_MISC_PORT16_INTERNAL_DESIGN #language en-US "P16ICD"
+#string STR_MISC_PORT16_EXTERNAL_DESIGN #language en-US "P16ECD"
+#string STR_MISC_PORT17_INTERNAL_DESIGN #language en-US "P17ICD"
+#string STR_MISC_PORT17_EXTERNAL_DESIGN #language en-US "P17ECD"
+#string STR_MISC_PORT18_INTERNAL_DESIGN #language en-US "P18ICD"
+#string STR_MISC_PORT18_EXTERNAL_DESIGN #language en-US "P18ECD"
+#string STR_MISC_PORT19_INTERNAL_DESIGN #language en-US "P19ICD"
+#string STR_MISC_PORT19_EXTERNAL_DESIGN #language en-US "P19ECD"
+#string STR_MISC_PORT20_INTERNAL_DESIGN #language en-US "P20ICD"
+#string STR_MISC_PORT20_EXTERNAL_DESIGN #language en-US "P20ECD"
+#string STR_MISC_PORT21_INTERNAL_DESIGN #language en-US "P21ICD"
+#string STR_MISC_PORT21_EXTERNAL_DESIGN #language en-US "P21ECD"
diff --git a/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscPortInternalConnectorDesignatorData.c b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscPortInternalConnectorDesignatorData.c
new file mode 100644
index 0000000000..2333c911c9
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscPortInternalConnectorDesignatorData.c
@@ -0,0 +1,190 @@
+/** @file
+This driver parses the mSmbiosMiscDataTable structure and reports
+any generated data to the DataHub.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+
+**/
+
+
+#include "CommonHeader.h"
+
+#include "SmbiosMisc.h"
+
+//
+// Static (possibly build generated) Bios Vendor data.
+//
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector1) = {
+ STRING_TOKEN (STR_MISC_PORT1_INTERNAL_DESIGN), // PortInternalConnectorDesignator
+ STRING_TOKEN (STR_MISC_PORT1_EXTERNAL_DESIGN), // PortExternalConnectorDesignator
+ EfiPortConnectorTypeNone, // PortInternalConnectorType
+ EfiPortConnectorTypePS2, // PortExternalConnectorType
+ EfiPortTypeKeyboard, // PortType
+ //mPs2KbyboardDevicePath // PortPath
+ {{{{0}}}}
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector2) = {
+ STRING_TOKEN (STR_MISC_PORT2_INTERNAL_DESIGN), // PortInternalConnectorDesignator
+ STRING_TOKEN (STR_MISC_PORT2_EXTERNAL_DESIGN), // PortExternalConnectorDesignator
+ EfiPortConnectorTypeNone, // PortInternalConnectorType
+ EfiPortConnectorTypePS2, // PortExternalConnectorType
+ EfiPortTypeMouse, // PortType
+ //mPs2MouseDevicePath // PortPath
+ {{{{0}}}}
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector3) = {
+ STRING_TOKEN (STR_MISC_PORT3_INTERNAL_DESIGN),
+ STRING_TOKEN (STR_MISC_PORT3_EXTERNAL_DESIGN),
+ EfiPortConnectorTypeOther,
+ EfiPortConnectorTypeNone,
+ EfiPortTypeSerial16550ACompatible,
+ //mCom1DevicePath
+ {{{{0}}}}
+};
+
+
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector4) = {
+ STRING_TOKEN (STR_MISC_PORT4_INTERNAL_DESIGN),
+ STRING_TOKEN (STR_MISC_PORT4_EXTERNAL_DESIGN),
+ EfiPortConnectorTypeNone,
+ EfiPortConnectorTypeRJ45,
+ EfiPortTypeSerial16550ACompatible,
+ //mCom2DevicePath
+ {{{{0}}}}
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector5) = {
+ STRING_TOKEN (STR_MISC_PORT5_INTERNAL_DESIGN),
+ STRING_TOKEN (STR_MISC_PORT5_EXTERNAL_DESIGN),
+ EfiPortConnectorTypeOther,
+ EfiPortConnectorTypeNone,
+ EfiPortTypeSerial16550ACompatible,
+ //mCom3DevicePath
+ {{{{0}}}}
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector6) = {
+ STRING_TOKEN (STR_MISC_PORT6_INTERNAL_DESIGN),
+ STRING_TOKEN (STR_MISC_PORT6_EXTERNAL_DESIGN),
+ EfiPortConnectorTypeNone,
+ EfiPortConnectorTypeRJ45,
+ EfiPortTypeSerial16550ACompatible,
+ //mCom3DevicePath
+ {{{{0}}}}
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector7) = {
+ STRING_TOKEN (STR_MISC_PORT7_INTERNAL_DESIGN),
+ STRING_TOKEN (STR_MISC_PORT7_EXTERNAL_DESIGN),
+ EfiPortConnectorTypeNone,
+ EfiPortConnectorTypeDB25Male,
+ EfiPortTypeParallelPortEcpEpp,
+ //mLpt1DevicePath
+ {{{{0}}}}
+};
+
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector8) = {
+ STRING_TOKEN (STR_MISC_PORT8_INTERNAL_DESIGN),
+ STRING_TOKEN (STR_MISC_PORT8_EXTERNAL_DESIGN),
+ EfiPortConnectorTypeNone,
+ EfiPortConnectorTypeUsb,
+ EfiPortTypeUsb,
+ //mUsb0DevicePath
+ {{{{0}}}}
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector9) = {
+ STRING_TOKEN (STR_MISC_PORT9_INTERNAL_DESIGN),
+ STRING_TOKEN (STR_MISC_PORT9_EXTERNAL_DESIGN),
+ EfiPortConnectorTypeNone,
+ EfiPortConnectorTypeUsb,
+ EfiPortTypeUsb,
+ //mUsb1DevicePath
+ {{{{0}}}}
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector10) = {
+ STRING_TOKEN (STR_MISC_PORT10_INTERNAL_DESIGN),
+ STRING_TOKEN (STR_MISC_PORT10_EXTERNAL_DESIGN),
+ EfiPortConnectorTypeNone,
+ EfiPortConnectorTypeUsb,
+ EfiPortTypeUsb,
+ //mUsb2DevicePath
+ {{{{0}}}}
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector11) = {
+ STRING_TOKEN (STR_MISC_PORT11_INTERNAL_DESIGN),
+ STRING_TOKEN (STR_MISC_PORT11_EXTERNAL_DESIGN),
+ EfiPortConnectorTypeNone,
+ EfiPortConnectorTypeUsb,
+ EfiPortTypeUsb,
+ //mUsb3DevicePath
+ {{{{0}}}}
+};
+
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector12) = {
+ STRING_TOKEN (STR_MISC_PORT12_INTERNAL_DESIGN),
+ STRING_TOKEN (STR_MISC_PORT12_EXTERNAL_DESIGN),
+ EfiPortConnectorTypeNone,
+ EfiPortConnectorTypeRJ45,
+ EfiPortTypeNetworkPort,
+ //mGbNicDevicePath
+ {{{{0}}}}
+};
+
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector13) = {
+ STRING_TOKEN (STR_MISC_PORT13_INTERNAL_DESIGN),
+ STRING_TOKEN (STR_MISC_PORT13_EXTERNAL_DESIGN),
+ EfiPortConnectorTypeOnboardFloppy,
+ EfiPortConnectorTypeNone,
+ EfiPortTypeOther,
+ //mFloopyADevicePath
+ {{{{0}}}}
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector14) = {
+ STRING_TOKEN (STR_MISC_PORT14_INTERNAL_DESIGN),
+ STRING_TOKEN (STR_MISC_PORT14_EXTERNAL_DESIGN),
+ EfiPortConnectorTypeOnboardIde,
+ EfiPortConnectorTypeNone,
+ EfiPortTypeOther,
+ //mIdeDevicePath
+ {{{{0}}}}
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector15) = {
+ STRING_TOKEN (STR_MISC_PORT15_INTERNAL_DESIGN),
+ STRING_TOKEN (STR_MISC_PORT15_EXTERNAL_DESIGN),
+ EfiPortConnectorTypeOnboardIde,
+ EfiPortConnectorTypeNone,
+ EfiPortTypeOther,
+ //mSataDevicePath
+ {{{{0}}}}
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector16) = {
+ STRING_TOKEN (STR_MISC_PORT16_INTERNAL_DESIGN),
+ STRING_TOKEN (STR_MISC_PORT16_EXTERNAL_DESIGN),
+ EfiPortConnectorTypeOnboardIde,
+ EfiPortConnectorTypeNone,
+ EfiPortTypeOther,
+ //mSataDevicePath
+ {{{{0}}}}
+};
+
diff --git a/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscPortInternalConnectorDesignatorFunction.c b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscPortInternalConnectorDesignatorFunction.c
new file mode 100644
index 0000000000..bb99c22734
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscPortInternalConnectorDesignatorFunction.c
@@ -0,0 +1,298 @@
+/** @file
+Port internal connector designator information boot time changes.
+SMBIOS type 8.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+
+**/
+
+
+#include "CommonHeader.h"
+
+#include "SmbiosMisc.h"
+
+//STATIC PS2_CONN_DEVICE_PATH mPs2KeyboardDevicePath = { DP_ACPI, DP_PCI( 0x1F,0x00 ),DP_LPC( 0x0303,0 ), DP_END };
+//STATIC PS2_CONN_DEVICE_PATH mPs2MouseDevicePath = { DP_ACPI, DP_PCI( 0x1F,0x00 ),DP_LPC( 0x0303,1 ), DP_END };
+//STATIC SERIAL_CONN_DEVICE_PATH mCom1DevicePath = { DP_ACPI, DP_PCI( 0x1F,0x00 ),DP_LPC( 0x0501,0 ), DP_END };
+//STATIC SERIAL_CONN_DEVICE_PATH mCom2DevicePath = { DP_ACPI, DP_PCI( 0x1F,0x00 ),DP_LPC( 0x0501,1 ), DP_END };
+//STATIC PARALLEL_CONN_DEVICE_PATH mLpt1DevicePath = { DP_ACPI, DP_PCI( 0x1F,0x00 ),DP_LPC( 0x0401,0 ), DP_END };
+//STATIC FLOOPY_CONN_DEVICE_PATH mFloopyADevicePath = { DP_ACPI, DP_PCI( 0x1F,0x00 ),DP_LPC( 0x0604,0 ), DP_END };
+//STATIC FLOOPY_CONN_DEVICE_PATH mFloopyBDevicePath = { DP_ACPI, DP_PCI( 0x1F,0x00 ),DP_LPC( 0x0604,1 ), DP_END };
+//STATIC USB_PORT_DEVICE_PATH mUsb0DevicePath = { DP_ACPI, DP_PCI( 0x1d,0x00 ), DP_END };
+//STATIC USB_PORT_DEVICE_PATH mUsb1DevicePath = { DP_ACPI, DP_PCI( 0x1d,0x01 ), DP_END };
+//STATIC USB_PORT_DEVICE_PATH mUsb2DevicePath = { DP_ACPI, DP_PCI( 0x1d,0x02 ), DP_END };
+//STATIC USB_PORT_DEVICE_PATH mUsb3DevicePath = { DP_ACPI, DP_PCI( 0x1d,0x03 ), DP_END };
+//STATIC IDE_DEVICE_PATH mIdeDevicePath = { DP_ACPI, DP_PCI( 0x1F,0x01 ), DP_END };
+//STATIC IDE_DEVICE_PATH mSata1DevicePath = { DP_ACPI, DP_PCI( 0x1F,0x02 ), DP_END };
+//STATIC GB_NIC_DEVICE_PATH mGbNicDevicePath = { DP_ACPI, DP_PCI( 0x03,0x00 ),DP_PCI( 0x1F,0x00 ),DP_PCI( 0x07,0x00 ), DP_END };
+EFI_DEVICE_PATH_PROTOCOL mEndDevicePath = DP_END;
+
+MISC_SMBIOS_DATA_TABLE_EXTERNS (EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector1);
+MISC_SMBIOS_DATA_TABLE_EXTERNS (EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector2);
+MISC_SMBIOS_DATA_TABLE_EXTERNS (EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector3);
+MISC_SMBIOS_DATA_TABLE_EXTERNS (EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector4);
+MISC_SMBIOS_DATA_TABLE_EXTERNS (EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector5);
+MISC_SMBIOS_DATA_TABLE_EXTERNS (EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector6);
+MISC_SMBIOS_DATA_TABLE_EXTERNS (EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector7);
+MISC_SMBIOS_DATA_TABLE_EXTERNS (EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector8);
+MISC_SMBIOS_DATA_TABLE_EXTERNS (EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector9);
+MISC_SMBIOS_DATA_TABLE_EXTERNS (EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector10);
+MISC_SMBIOS_DATA_TABLE_EXTERNS (EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector11);
+MISC_SMBIOS_DATA_TABLE_EXTERNS (EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector12);
+MISC_SMBIOS_DATA_TABLE_EXTERNS (EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector13);
+MISC_SMBIOS_DATA_TABLE_EXTERNS (EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector14);
+
+
+EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR *mMiscConnectorArray[SMBIOS_PORT_CONNECTOR_MAX_NUM] =
+{
+ MISC_SMBIOS_DATA_TABLE_POINTER(MiscPortConnector1),
+ MISC_SMBIOS_DATA_TABLE_POINTER(MiscPortConnector2),
+ MISC_SMBIOS_DATA_TABLE_POINTER(MiscPortConnector3),
+ MISC_SMBIOS_DATA_TABLE_POINTER(MiscPortConnector4),
+ MISC_SMBIOS_DATA_TABLE_POINTER(MiscPortConnector5),
+ MISC_SMBIOS_DATA_TABLE_POINTER(MiscPortConnector6),
+ MISC_SMBIOS_DATA_TABLE_POINTER(MiscPortConnector7),
+ MISC_SMBIOS_DATA_TABLE_POINTER(MiscPortConnector8),
+ MISC_SMBIOS_DATA_TABLE_POINTER(MiscPortConnector9),
+ MISC_SMBIOS_DATA_TABLE_POINTER(MiscPortConnector10),
+ MISC_SMBIOS_DATA_TABLE_POINTER(MiscPortConnector11),
+ MISC_SMBIOS_DATA_TABLE_POINTER(MiscPortConnector12),
+ MISC_SMBIOS_DATA_TABLE_POINTER(MiscPortConnector13),
+ MISC_SMBIOS_DATA_TABLE_POINTER(MiscPortConnector14),
+};
+
+BOOLEAN PcdMiscPortIsInit = FALSE;
+SMBIOS_PORT_CONNECTOR_DESIGNATOR_COFNIG SMBIOSPortConnector = {0};
+
+
+/**
+ Get Misc Port Configuration information from PCD
+ @param SMBIOSPortConnector Pointer to SMBIOSPortConnector table.
+
+**/
+
+VOID
+GetMiscPortConfigFromPcd ()
+{
+ //
+ // Type 8
+ //
+ SMBIOSPortConnector.SMBIOSConnectorNumber = PcdGet8 (PcdSMBIOSConnectorNumber);
+ AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSPort1InternalConnectorDesignator), SMBIOSPortConnector.SMBIOSPortConnector[0].PortInternalConnectorDesignator);
+ AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSPort1ExternalConnectorDesignator), SMBIOSPortConnector.SMBIOSPortConnector[0].PortExternalConnectorDesignator);
+ SMBIOSPortConnector.SMBIOSPortConnector[0].PortInternalConnectorType = PcdGet8 (PcdSMBIOSPort1InternalConnectorType);
+ SMBIOSPortConnector.SMBIOSPortConnector[0].PortExternalConnectorType = PcdGet8 (PcdSMBIOSPort1ExternalConnectorType);
+ SMBIOSPortConnector.SMBIOSPortConnector[0].PortType = PcdGet8 (PcdSMBIOSPort1Type);
+
+ AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSPort2InternalConnectorDesignator), SMBIOSPortConnector.SMBIOSPortConnector[1].PortInternalConnectorDesignator);
+ AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSPort2ExternalConnectorDesignator), SMBIOSPortConnector.SMBIOSPortConnector[1].PortExternalConnectorDesignator);
+ SMBIOSPortConnector.SMBIOSPortConnector[1].PortInternalConnectorType = PcdGet8 (PcdSMBIOSPort2InternalConnectorType);
+ SMBIOSPortConnector.SMBIOSPortConnector[1].PortExternalConnectorType = PcdGet8 (PcdSMBIOSPort2ExternalConnectorType);
+ SMBIOSPortConnector.SMBIOSPortConnector[1].PortType = PcdGet8 (PcdSMBIOSPort2Type);
+
+ AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSPort3InternalConnectorDesignator), SMBIOSPortConnector.SMBIOSPortConnector[2].PortInternalConnectorDesignator);
+ AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSPort3ExternalConnectorDesignator), SMBIOSPortConnector.SMBIOSPortConnector[2].PortExternalConnectorDesignator);
+ SMBIOSPortConnector.SMBIOSPortConnector[2].PortInternalConnectorType = PcdGet8 (PcdSMBIOSPort3InternalConnectorType);
+ SMBIOSPortConnector.SMBIOSPortConnector[2].PortExternalConnectorType = PcdGet8 (PcdSMBIOSPort3ExternalConnectorType);
+ SMBIOSPortConnector.SMBIOSPortConnector[2].PortType = PcdGet8 (PcdSMBIOSPort3Type);
+
+ AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSPort4InternalConnectorDesignator), SMBIOSPortConnector.SMBIOSPortConnector[3].PortInternalConnectorDesignator);
+ AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSPort4ExternalConnectorDesignator), SMBIOSPortConnector.SMBIOSPortConnector[3].PortExternalConnectorDesignator);
+ SMBIOSPortConnector.SMBIOSPortConnector[3].PortInternalConnectorType = PcdGet8 (PcdSMBIOSPort4InternalConnectorType);
+ SMBIOSPortConnector.SMBIOSPortConnector[3].PortExternalConnectorType = PcdGet8 (PcdSMBIOSPort4ExternalConnectorType);
+ SMBIOSPortConnector.SMBIOSPortConnector[3].PortType = PcdGet8 (PcdSMBIOSPort4Type);
+
+ AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSPort5InternalConnectorDesignator), SMBIOSPortConnector.SMBIOSPortConnector[4].PortInternalConnectorDesignator);
+ AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSPort5ExternalConnectorDesignator), SMBIOSPortConnector.SMBIOSPortConnector[4].PortExternalConnectorDesignator);
+ SMBIOSPortConnector.SMBIOSPortConnector[4].PortInternalConnectorType = PcdGet8 (PcdSMBIOSPort5InternalConnectorType);
+ SMBIOSPortConnector.SMBIOSPortConnector[4].PortExternalConnectorType = PcdGet8 (PcdSMBIOSPort5ExternalConnectorType);
+ SMBIOSPortConnector.SMBIOSPortConnector[4].PortType = PcdGet8 (PcdSMBIOSPort5Type);
+
+ AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSPort6InternalConnectorDesignator), SMBIOSPortConnector.SMBIOSPortConnector[5].PortInternalConnectorDesignator);
+ AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSPort6ExternalConnectorDesignator), SMBIOSPortConnector.SMBIOSPortConnector[5].PortExternalConnectorDesignator);
+ SMBIOSPortConnector.SMBIOSPortConnector[5].PortInternalConnectorType = PcdGet8 (PcdSMBIOSPort6InternalConnectorType);
+ SMBIOSPortConnector.SMBIOSPortConnector[5].PortExternalConnectorType = PcdGet8 (PcdSMBIOSPort6ExternalConnectorType);
+ SMBIOSPortConnector.SMBIOSPortConnector[5].PortType = PcdGet8 (PcdSMBIOSPort6Type);
+
+ AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSPort7InternalConnectorDesignator), SMBIOSPortConnector.SMBIOSPortConnector[6].PortInternalConnectorDesignator);
+ AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSPort7ExternalConnectorDesignator), SMBIOSPortConnector.SMBIOSPortConnector[6].PortExternalConnectorDesignator);
+ SMBIOSPortConnector.SMBIOSPortConnector[6].PortInternalConnectorType = PcdGet8 (PcdSMBIOSPort7InternalConnectorType);
+ SMBIOSPortConnector.SMBIOSPortConnector[6].PortExternalConnectorType = PcdGet8 (PcdSMBIOSPort7ExternalConnectorType);
+ SMBIOSPortConnector.SMBIOSPortConnector[6].PortType = PcdGet8 (PcdSMBIOSPort7Type);
+
+ AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSPort8InternalConnectorDesignator), SMBIOSPortConnector.SMBIOSPortConnector[7].PortInternalConnectorDesignator);
+ AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSPort8ExternalConnectorDesignator), SMBIOSPortConnector.SMBIOSPortConnector[7].PortExternalConnectorDesignator);
+ SMBIOSPortConnector.SMBIOSPortConnector[7].PortInternalConnectorType = PcdGet8 (PcdSMBIOSPort8InternalConnectorType);
+ SMBIOSPortConnector.SMBIOSPortConnector[7].PortExternalConnectorType = PcdGet8 (PcdSMBIOSPort8ExternalConnectorType);
+ SMBIOSPortConnector.SMBIOSPortConnector[7].PortType = PcdGet8 (PcdSMBIOSPort8Type);
+
+ AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSPort9InternalConnectorDesignator), SMBIOSPortConnector.SMBIOSPortConnector[8].PortInternalConnectorDesignator);
+ AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSPort9ExternalConnectorDesignator), SMBIOSPortConnector.SMBIOSPortConnector[8].PortExternalConnectorDesignator);
+ SMBIOSPortConnector.SMBIOSPortConnector[8].PortInternalConnectorType = PcdGet8 (PcdSMBIOSPort9InternalConnectorType);
+ SMBIOSPortConnector.SMBIOSPortConnector[8].PortExternalConnectorType = PcdGet8 (PcdSMBIOSPort9ExternalConnectorType);
+ SMBIOSPortConnector.SMBIOSPortConnector[8].PortType = PcdGet8 (PcdSMBIOSPort9Type);
+
+ AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSPort10InternalConnectorDesignator), SMBIOSPortConnector.SMBIOSPortConnector[9].PortInternalConnectorDesignator);
+ AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSPort10ExternalConnectorDesignator), SMBIOSPortConnector.SMBIOSPortConnector[9].PortExternalConnectorDesignator);
+ SMBIOSPortConnector.SMBIOSPortConnector[9].PortInternalConnectorType = PcdGet8 (PcdSMBIOSPort10InternalConnectorType);
+ SMBIOSPortConnector.SMBIOSPortConnector[9].PortExternalConnectorType = PcdGet8 (PcdSMBIOSPort10ExternalConnectorType);
+ SMBIOSPortConnector.SMBIOSPortConnector[9].PortType = PcdGet8 (PcdSMBIOSPort10Type);
+
+ AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSPort11InternalConnectorDesignator), SMBIOSPortConnector.SMBIOSPortConnector[10].PortInternalConnectorDesignator);
+ AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSPort11ExternalConnectorDesignator), SMBIOSPortConnector.SMBIOSPortConnector[10].PortExternalConnectorDesignator);
+ SMBIOSPortConnector.SMBIOSPortConnector[10].PortInternalConnectorType = PcdGet8 (PcdSMBIOSPort11InternalConnectorType);
+ SMBIOSPortConnector.SMBIOSPortConnector[10].PortExternalConnectorType = PcdGet8 (PcdSMBIOSPort11ExternalConnectorType);
+ SMBIOSPortConnector.SMBIOSPortConnector[10].PortType = PcdGet8 (PcdSMBIOSPort11Type);
+
+ AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSPort12InternalConnectorDesignator), SMBIOSPortConnector.SMBIOSPortConnector[11].PortInternalConnectorDesignator);
+ AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSPort12ExternalConnectorDesignator), SMBIOSPortConnector.SMBIOSPortConnector[11].PortExternalConnectorDesignator);
+ SMBIOSPortConnector.SMBIOSPortConnector[11].PortInternalConnectorType = PcdGet8 (PcdSMBIOSPort12InternalConnectorType);
+ SMBIOSPortConnector.SMBIOSPortConnector[11].PortExternalConnectorType = PcdGet8 (PcdSMBIOSPort12ExternalConnectorType);
+ SMBIOSPortConnector.SMBIOSPortConnector[11].PortType = PcdGet8 (PcdSMBIOSPort12Type);
+
+ AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSPort13InternalConnectorDesignator), SMBIOSPortConnector.SMBIOSPortConnector[12].PortInternalConnectorDesignator);
+ AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSPort13ExternalConnectorDesignator), SMBIOSPortConnector.SMBIOSPortConnector[12].PortExternalConnectorDesignator);
+ SMBIOSPortConnector.SMBIOSPortConnector[12].PortInternalConnectorType = PcdGet8 (PcdSMBIOSPort13InternalConnectorType);
+ SMBIOSPortConnector.SMBIOSPortConnector[12].PortExternalConnectorType = PcdGet8 (PcdSMBIOSPort13ExternalConnectorType);
+ SMBIOSPortConnector.SMBIOSPortConnector[12].PortType = PcdGet8 (PcdSMBIOSPort13Type);
+
+ AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSPort14InternalConnectorDesignator), SMBIOSPortConnector.SMBIOSPortConnector[13].PortInternalConnectorDesignator);
+ AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSPort14ExternalConnectorDesignator), SMBIOSPortConnector.SMBIOSPortConnector[13].PortExternalConnectorDesignator);
+ SMBIOSPortConnector.SMBIOSPortConnector[13].PortInternalConnectorType = PcdGet8 (PcdSMBIOSPort14InternalConnectorType);
+ SMBIOSPortConnector.SMBIOSPortConnector[13].PortExternalConnectorType = PcdGet8 (PcdSMBIOSPort14ExternalConnectorType);
+ SMBIOSPortConnector.SMBIOSPortConnector[13].PortType = PcdGet8 (PcdSMBIOSPort14Type);
+}
+/**
+ This function makes boot time changes to the contents of the
+ MiscPortConnectorInformation (Type 8).
+
+ @param RecordData Pointer to copy of RecordData from the Data Table.
+
+ @retval EFI_SUCCESS All parameters were valid.
+ @retval EFI_UNSUPPORTED Unexpected RecordType value.
+ @retval EFI_INVALID_PARAMETER Invalid parameter was found.
+
+**/
+MISC_SMBIOS_TABLE_FUNCTION(MiscPortInternalConnectorDesignator)
+{
+ CHAR8 *OptionalStrStart;
+ UINTN InternalRefStrLen;
+ UINTN ExternalRefStrLen;
+ EFI_STRING InternalRef;
+ EFI_STRING ExternalRef;
+ STRING_REF TokenForInternal;
+ STRING_REF TokenForExternal;
+ STRING_REF TokenToUpdate;
+ UINT8 InternalType;
+ UINT8 ExternalType;
+ UINT8 PortType;
+ EFI_STATUS Status;
+ SMBIOS_TABLE_TYPE8 *SmbiosRecord;
+ EFI_SMBIOS_HANDLE SmbiosHandle;
+ EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR *ForType8InputData;
+ UINT8 Index;
+
+ ForType8InputData = (EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR *)RecordData;
+ //
+ // First check for invalid parameters.
+ //
+ if (RecordData == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ TokenForInternal = 0;
+ TokenForExternal = 0;
+ InternalType = 0;
+ ExternalType = 0;
+ PortType = 0;
+
+ if (!PcdMiscPortIsInit) {
+ GetMiscPortConfigFromPcd ();
+ PcdMiscPortIsInit = TRUE;
+ }
+
+ for (Index = 0; Index < SMBIOS_PORT_CONNECTOR_MAX_NUM; Index++) {
+ if (ForType8InputData->PortInternalConnectorDesignator == (mMiscConnectorArray[Index])->PortInternalConnectorDesignator) {
+ //DEBUG ((EFI_D_ERROR, "Found Port Connector Data %d : ", Index));
+ break;
+ }
+ }
+ if (Index >= SMBIOSPortConnector.SMBIOSConnectorNumber) {
+ return EFI_SUCCESS;
+ }
+
+ if (Index >= SMBIOS_PORT_CONNECTOR_MAX_NUM) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ InternalRef = SMBIOSPortConnector.SMBIOSPortConnector[Index].PortInternalConnectorDesignator;
+ if (StrLen (InternalRef) > 0) {
+ TokenToUpdate = STRING_TOKEN ((mMiscConnectorArray[Index])->PortInternalConnectorDesignator);
+ HiiSetString (mHiiHandle, TokenToUpdate, InternalRef, NULL);
+ }
+ ExternalRef = SMBIOSPortConnector.SMBIOSPortConnector[Index].PortExternalConnectorDesignator;
+ if (StrLen (ExternalRef) > 0) {
+ TokenToUpdate = STRING_TOKEN ((mMiscConnectorArray[Index])->PortExternalConnectorDesignator);
+ HiiSetString (mHiiHandle, TokenToUpdate, ExternalRef, NULL);
+ }
+ TokenForInternal = STRING_TOKEN ((mMiscConnectorArray[Index])->PortInternalConnectorDesignator);
+ TokenForExternal = STRING_TOKEN ((mMiscConnectorArray[Index])->PortExternalConnectorDesignator);
+ InternalType = SMBIOSPortConnector.SMBIOSPortConnector[Index].PortInternalConnectorType;
+ ExternalType = SMBIOSPortConnector.SMBIOSPortConnector[Index].PortExternalConnectorType;
+ PortType = SMBIOSPortConnector.SMBIOSPortConnector[Index].PortType;
+
+ InternalRef = HiiGetPackageString(&gEfiCallerIdGuid, TokenForInternal, NULL);
+ InternalRefStrLen = StrLen(InternalRef);
+ if (InternalRefStrLen > SMBIOS_STRING_MAX_LENGTH) {
+ return EFI_UNSUPPORTED;
+ }
+
+ ExternalRef = HiiGetPackageString(&gEfiCallerIdGuid, TokenForExternal, NULL);
+ ExternalRefStrLen = StrLen(ExternalRef);
+ if (ExternalRefStrLen > SMBIOS_STRING_MAX_LENGTH) {
+ return EFI_UNSUPPORTED;
+ }
+ //
+ // Two zeros following the last string.
+ //
+ SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE8) + InternalRefStrLen + 1 + ExternalRefStrLen + 1 + 1);
+ ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE8) + InternalRefStrLen + 1 + ExternalRefStrLen + 1 + 1);
+
+ SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_PORT_CONNECTOR_INFORMATION;
+ SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE8);
+ //
+ // Make handle chosen by smbios protocol.add automatically.
+ //
+ SmbiosRecord->Hdr.Handle = 0;
+ SmbiosRecord->InternalReferenceDesignator = 1;
+ SmbiosRecord->InternalConnectorType = InternalType;
+ SmbiosRecord->ExternalReferenceDesignator = 2;
+ SmbiosRecord->ExternalConnectorType = ExternalType;
+ SmbiosRecord->PortType = PortType;
+
+ OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
+ UnicodeStrToAsciiStr(InternalRef, OptionalStrStart);
+ UnicodeStrToAsciiStr(ExternalRef, OptionalStrStart + InternalRefStrLen + 1);
+
+ //
+ // Now we have got the full smbios record, call smbios protocol to add this record.
+ //
+ SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+ Status = Smbios-> Add(
+ Smbios,
+ NULL,
+ &SmbiosHandle,
+ (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
+ );
+ FreePool(SmbiosRecord);
+ return Status;
+}
diff --git a/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemManufacturer.uni b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemManufacturer.uni
new file mode 100644
index 0000000000..296293e54d
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemManufacturer.uni
@@ -0,0 +1,26 @@
+// /** @file
+// System Manufacturer Information
+//
+// Copyright (c) 2013-2015 Intel Corporation.
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+//
+// **/
+
+
+/=#
+
+
+#string STR_MISC_SYSTEM_MANUFACTURER #language en-US "Intel Corp."
+#string STR_MISC_SYSTEM_PRODUCT_NAME #language en-US "QUARK"
+#string STR_MISC_SYSTEM_VERSION #language en-US "1.0"
+#string STR_MISC_SYSTEM_SERIAL_NUMBER #language en-US "Unknown"
+#string STR_MISC_SYSTEM_SKU_NUMBER #language en-US "System SKUNumber"
+#string STR_MISC_SYSTEM_FAMILY #language en-US "X1000"
diff --git a/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemManufacturerData.c b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemManufacturerData.c
new file mode 100644
index 0000000000..2d30e6f949
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemManufacturerData.c
@@ -0,0 +1,38 @@
+/** @file
+This driver parses the mMiscSubclassDataTable structure and reports
+any generated data using smbios protocol.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+
+**/
+
+
+#include "CommonHeader.h"
+
+#include "SmbiosMisc.h"
+
+
+//
+// Static (possibly build generated) System Manufacturer data.
+//
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_MANUFACTURER, MiscSystemManufacturer) = {
+ STRING_TOKEN(STR_MISC_SYSTEM_MANUFACTURER), // SystemManufactrurer
+ STRING_TOKEN(STR_MISC_SYSTEM_PRODUCT_NAME), // SystemProductName
+ STRING_TOKEN(STR_MISC_SYSTEM_VERSION), // SystemVersion
+ STRING_TOKEN(STR_MISC_SYSTEM_SERIAL_NUMBER), // SystemSerialNumber
+ { // SystemUuid
+ 0x13ffef23, 0x8654, 0x46da, {0xa4, 0x7, 0x39, 0xc9, 0x12, 0x2, 0xd3, 0x56}
+ },
+ EfiSystemWakeupTypePowerSwitch, // SystemWakeupType
+ STRING_TOKEN(STR_MISC_SYSTEM_SKU_NUMBER), // SystemSKUNumber
+ STRING_TOKEN(STR_MISC_SYSTEM_FAMILY), // SystemFamily
+};
diff --git a/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemManufacturerFunction.c b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemManufacturerFunction.c
new file mode 100644
index 0000000000..d456de6716
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemManufacturerFunction.c
@@ -0,0 +1,204 @@
+/** @file
+This driver parses the mMiscSubclassDataTable structure and reports
+any generated data to smbios.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+
+**/
+
+
+#include "CommonHeader.h"
+
+#include "SmbiosMisc.h"
+
+/**
+ This function makes boot time changes to the contents of the
+ MiscSystemManufacturer (Type 1).
+
+ @param RecordData Pointer to copy of RecordData from the Data Table.
+
+ @retval EFI_SUCCESS All parameters were valid.
+ @retval EFI_UNSUPPORTED Unexpected RecordType value.
+ @retval EFI_INVALID_PARAMETER Invalid parameter was found.
+
+**/
+MISC_SMBIOS_TABLE_FUNCTION(MiscSystemManufacturer)
+{
+ CHAR8 *OptionalStrStart;
+ UINTN ManuStrLen;
+ UINTN VerStrLen;
+ UINTN PdNameStrLen;
+ UINTN SerialNumStrLen;
+ UINTN SKUNumStrLen;
+ UINTN FamilyStrLen;
+ EFI_STATUS Status;
+ CHAR16 Manufacturer[SMBIOS_STRING_MAX_LENGTH];
+ CHAR16 ProductName[SMBIOS_STRING_MAX_LENGTH];
+ CHAR16 Version[SMBIOS_STRING_MAX_LENGTH];
+ CHAR16 SerialNumber[SMBIOS_STRING_MAX_LENGTH];
+ CHAR16 SKUNumber[SMBIOS_STRING_MAX_LENGTH];
+ CHAR16 Family[SMBIOS_STRING_MAX_LENGTH];
+ EFI_STRING ManufacturerPtr;
+ EFI_STRING ProductNamePtr;
+ EFI_STRING VersionPtr;
+ EFI_STRING SerialNumberPtr;
+ EFI_STRING SKUNumberPtr;
+ EFI_STRING FamilyPtr;
+ STRING_REF TokenToGet;
+ STRING_REF TokenToUpdate;
+ EFI_SMBIOS_HANDLE SmbiosHandle;
+ SMBIOS_TABLE_TYPE1 *SmbiosRecord;
+ EFI_MISC_SYSTEM_MANUFACTURER *ForType1InputData;
+
+ ForType1InputData = (EFI_MISC_SYSTEM_MANUFACTURER *)RecordData;
+
+ //
+ // First check for invalid parameters.
+ //
+ if (RecordData == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Update strings from PCD
+ //
+ AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSSystemManufacturer), Manufacturer);
+ if (StrLen (Manufacturer) > 0) {
+ TokenToUpdate = STRING_TOKEN (STR_MISC_SYSTEM_MANUFACTURER);
+ HiiSetString (mHiiHandle, TokenToUpdate, Manufacturer, NULL);
+ }
+ TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_MANUFACTURER);
+ ManufacturerPtr = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL);
+ ManuStrLen = StrLen(ManufacturerPtr);
+ if (ManuStrLen > SMBIOS_STRING_MAX_LENGTH) {
+ return EFI_UNSUPPORTED;
+ }
+
+ AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSSystemProductName), ProductName);
+ if (StrLen (ProductName) > 0) {
+ TokenToUpdate = STRING_TOKEN (STR_MISC_SYSTEM_PRODUCT_NAME);
+ HiiSetString (mHiiHandle, TokenToUpdate, ProductName, NULL);
+ }
+ TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_PRODUCT_NAME);
+ ProductNamePtr = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL);
+ PdNameStrLen = StrLen(ProductNamePtr);
+ if (PdNameStrLen > SMBIOS_STRING_MAX_LENGTH) {
+ return EFI_UNSUPPORTED;
+ }
+
+ AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSSystemVersion), Version);
+ if (StrLen (Version) > 0) {
+ TokenToUpdate = STRING_TOKEN (STR_MISC_SYSTEM_VERSION);
+ HiiSetString (mHiiHandle, TokenToUpdate, Version, NULL);
+ }
+ TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_VERSION);
+ VersionPtr = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL);
+ VerStrLen = StrLen(VersionPtr);
+ if (VerStrLen > SMBIOS_STRING_MAX_LENGTH) {
+ return EFI_UNSUPPORTED;
+ }
+
+ AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSSystemSerialNumber), SerialNumber);
+ if (StrLen (SerialNumber) > 0) {
+ TokenToUpdate = STRING_TOKEN (STR_MISC_SYSTEM_SERIAL_NUMBER);
+ HiiSetString (mHiiHandle, TokenToUpdate, SerialNumber, NULL);
+ }
+ TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_SERIAL_NUMBER);
+ SerialNumberPtr = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL);
+ SerialNumStrLen = StrLen(SerialNumberPtr);
+ if (SerialNumStrLen > SMBIOS_STRING_MAX_LENGTH) {
+ return EFI_UNSUPPORTED;
+ }
+
+ AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSSystemSKUNumber), SKUNumber);
+ if (StrLen (SKUNumber) > 0) {
+ TokenToUpdate = STRING_TOKEN (STR_MISC_SYSTEM_SKU_NUMBER);
+ HiiSetString (mHiiHandle, TokenToUpdate, SKUNumber, NULL);
+ }
+ TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_SKU_NUMBER);
+ SKUNumberPtr = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL);
+ SKUNumStrLen = StrLen(SKUNumberPtr);
+ if (SKUNumStrLen > SMBIOS_STRING_MAX_LENGTH) {
+ return EFI_UNSUPPORTED;
+ }
+
+ AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSSystemFamily), Family);
+ if (StrLen (Family) > 0) {
+ TokenToUpdate = STRING_TOKEN (STR_MISC_SYSTEM_FAMILY);
+ HiiSetString (mHiiHandle, TokenToUpdate, Family, NULL);
+ }
+ TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_FAMILY);
+ FamilyPtr = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL);
+ FamilyStrLen = StrLen(FamilyPtr);
+ if (FamilyStrLen > SMBIOS_STRING_MAX_LENGTH) {
+ return EFI_UNSUPPORTED;
+ }
+ //
+ // Two zeros following the last string.
+ //
+ SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE1) + ManuStrLen + 1 + PdNameStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1 + SKUNumStrLen + 1 + FamilyStrLen + 1 + 1);
+ ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE1) + ManuStrLen + 1 + PdNameStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1 + SKUNumStrLen + 1 + FamilyStrLen + 1 + 1);
+
+ SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_SYSTEM_INFORMATION;
+ SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE1);
+ //
+ // Make handle chosen by smbios protocol.add automatically.
+ //
+ SmbiosRecord->Hdr.Handle = 0;
+ //
+ // Manu will be the 1st optional string following the formatted structure.
+ //
+ SmbiosRecord->Manufacturer = 1;
+ //
+ // ProductName will be the 2nd optional string following the formatted structure.
+ //
+ SmbiosRecord->ProductName = 2;
+ //
+ // Version will be the 3rd optional string following the formatted structure.
+ //
+ SmbiosRecord->Version = 3;
+ //
+ // Serial number will be the 4th optional string following the formatted structure.
+ //
+ SmbiosRecord->SerialNumber = 4;
+ //
+ // SKU number will be the 5th optional string following the formatted structure.
+ //
+ SmbiosRecord->SKUNumber = 5;
+ //
+ // Family will be the 6th optional string following the formatted structure.
+ //
+ SmbiosRecord->Family = 6;
+ CopyMem ((UINT8 *) (&SmbiosRecord->Uuid), (UINT8 *)PcdGetPtr(PcdSMBIOSSystemUuid),16);
+ SmbiosRecord->WakeUpType = (UINT8)ForType1InputData->SystemWakeupType;
+
+ OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
+ UnicodeStrToAsciiStr(ManufacturerPtr, OptionalStrStart);
+ UnicodeStrToAsciiStr(ProductNamePtr, OptionalStrStart + ManuStrLen + 1);
+ UnicodeStrToAsciiStr(VersionPtr, OptionalStrStart + ManuStrLen + 1 + PdNameStrLen + 1);
+ UnicodeStrToAsciiStr(SerialNumberPtr, OptionalStrStart + ManuStrLen + 1 + PdNameStrLen + 1 + VerStrLen + 1);
+ UnicodeStrToAsciiStr(SKUNumberPtr, OptionalStrStart + ManuStrLen + 1 + PdNameStrLen + 1 + VerStrLen + 1 + SerialNumStrLen+ 1);
+ UnicodeStrToAsciiStr(FamilyPtr, OptionalStrStart + ManuStrLen + 1 + PdNameStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1 + SKUNumStrLen+ 1);
+
+ //
+ // Now we have got the full smbios record, call smbios protocol to add this record.
+ //
+ SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+ Status = Smbios-> Add(
+ Smbios,
+ NULL,
+ &SmbiosHandle,
+ (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
+ );
+ FreePool(SmbiosRecord);
+ return Status;
+}
diff --git a/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemOptionString.uni b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemOptionString.uni
new file mode 100644
index 0000000000..b124b52370
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemOptionString.uni
@@ -0,0 +1,20 @@
+// /** @file
+// Miscellaneous System Option Strings
+//
+// Copyright (c) 2013-2015 Intel Corporation.
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+//
+// **/
+
+
+/=#
+
+#string STR_MISC_SYSTEM_OPTION_STRING #language en-US "J1D4:1-2,5-6,9-10Default;2-3CMOS clr,6-7Pswd clr,10-11Recovery"
diff --git a/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemOptionStringData.c b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemOptionStringData.c
new file mode 100644
index 0000000000..58c7c6f8f9
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemOptionStringData.c
@@ -0,0 +1,29 @@
+/** @file
+This driver parses the mSmbiosMiscDataTable structure and reports
+any generated data to smbios.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+
+**/
+
+
+#include "CommonHeader.h"
+
+#include "SmbiosMisc.h"
+
+
+//
+// Static (possibly build generated) Bios Vendor data.
+//
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_OPTION_STRING, SystemOptionString) = {
+ {STRING_TOKEN (STR_MISC_SYSTEM_OPTION_STRING)}
+};
diff --git a/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemOptionStringFunction.c b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemOptionStringFunction.c
new file mode 100644
index 0000000000..44cc684d64
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemOptionStringFunction.c
@@ -0,0 +1,90 @@
+/** @file
+BIOS system option string boot time changes.
+SMBIOS type 12.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+
+**/
+
+
+#include "CommonHeader.h"
+#include "SmbiosMisc.h"
+
+
+/**
+ This function makes boot time changes to the contents of the
+ MiscSystemOptionString (Type 12).
+
+ @param RecordData Pointer to copy of RecordData from the Data Table.
+
+ @retval EFI_SUCCESS All parameters were valid.
+ @retval EFI_UNSUPPORTED Unexpected RecordType value.
+ @retval EFI_INVALID_PARAMETER Invalid parameter was found.
+
+**/
+MISC_SMBIOS_TABLE_FUNCTION(SystemOptionString)
+{
+ CHAR8 *OptionalStrStart;
+ UINTN OptStrLen;
+ EFI_STRING OptionString;
+ EFI_STATUS Status;
+ STRING_REF TokenToGet;
+ EFI_SMBIOS_HANDLE SmbiosHandle;
+ SMBIOS_TABLE_TYPE12 *SmbiosRecord;
+ EFI_MISC_SYSTEM_OPTION_STRING *ForType12InputData;
+
+ ForType12InputData = (EFI_MISC_SYSTEM_OPTION_STRING *)RecordData;
+
+ //
+ // First check for invalid parameters.
+ //
+ if (RecordData == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_OPTION_STRING);
+ OptionString = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL);
+ OptStrLen = StrLen(OptionString);
+ if (OptStrLen > SMBIOS_STRING_MAX_LENGTH) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Two zeros following the last string.
+ //
+ SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE12) + OptStrLen + 1 + 1);
+ ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE12) + OptStrLen + 1 + 1);
+
+ SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_SYSTEM_CONFIGURATION_OPTIONS;
+ SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE12);
+ //
+ // Make handle chosen by smbios protocol.add automatically.
+ //
+ SmbiosRecord->Hdr.Handle = 0;
+
+ SmbiosRecord->StringCount = 1;
+ OptionalStrStart = (CHAR8*) (SmbiosRecord + 1);
+ UnicodeStrToAsciiStr(OptionString, OptionalStrStart);
+ //
+ // Now we have got the full smbios record, call smbios protocol to add this record.
+ //
+ SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+ Status = Smbios-> Add(
+ Smbios,
+ NULL,
+ &SmbiosHandle,
+ (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
+ );
+
+ FreePool(SmbiosRecord);
+ return Status;
+}
diff --git a/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemSlotDesignation.uni b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemSlotDesignation.uni
new file mode 100644
index 0000000000..abf3aab6ff
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemSlotDesignation.uni
@@ -0,0 +1,33 @@
+// /** @file
+// Miscellaneous Port Connector Information
+//
+// Copyright (c) 2013-2015 Intel Corporation.
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+//
+// **/
+
+
+/=#
+
+#string STR_MISC_SYSTEM_SLOT1 #language en-US "SLOT1"
+#string STR_MISC_SYSTEM_SLOT2 #language en-US "SLOT2"
+#string STR_MISC_SYSTEM_SLOT3 #language en-US "SLOT3"
+#string STR_MISC_SYSTEM_SLOT4 #language en-US "SLOT4"
+#string STR_MISC_SYSTEM_SLOT5 #language en-US "SLOT5"
+#string STR_MISC_SYSTEM_SLOT6 #language en-US "SLOT6"
+#string STR_MISC_SYSTEM_SLOT7 #language en-US "SLOT7"
+#string STR_MISC_SYSTEM_SLOT8 #language en-US "SLOT8"
+#string STR_MISC_SYSTEM_SLOT9 #language en-US "SLOT9"
+#string STR_MISC_SYSTEM_SLOT10 #language en-US "SLOT10"
+#string STR_MISC_SYSTEM_SLOT11 #language en-US "SLOT11"
+#string STR_MISC_SYSTEM_SLOT12 #language en-US "SLOT12"
+#string STR_MISC_SYSTEM_SLOT13 #language en-US "SLOT13"
+#string STR_MISC_SYSTEM_SLOT14 #language en-US "SLOT14"
diff --git a/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemSlotDesignationData.c b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemSlotDesignationData.c
new file mode 100644
index 0000000000..d6764b133d
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemSlotDesignationData.c
@@ -0,0 +1,363 @@
+/** @file
+This driver parses the mMiscSubclassDataTable structure and reports
+any generated data to the DataHub.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+
+**/
+
+
+#include "CommonHeader.h"
+
+#include "SmbiosMisc.h"
+
+
+//
+// Static (possibly build generated) Bios Vendor data.
+//
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot1) = {
+ STRING_TOKEN(STR_MISC_SYSTEM_SLOT1), // SlotDesignation
+ EfiSlotTypePci, // SlotType
+ EfiSlotDataBusWidth32Bit, // SlotDataBusWidth
+ EfiSlotUsageAvailable, // SlotUsage
+ EfiSlotLengthLong , // SlotLength
+ 1, // SlotId
+ { // SlotCharacteristics
+ 0, // CharacteristicsUnknown :1;
+ 0, // Provides50Volts :1;
+ 1, // Provides33Volts :1;
+ 0, // SharedSlot :1;
+ 0, // PcCard16Supported :1;
+ 0, // CardBusSupported :1;
+ 0, // ZoomVideoSupported :1;
+ 0, // ModemRingResumeSupported:1;
+ 1, // PmeSignalSupported :1;
+ 0, // HotPlugDevicesSupported :1;
+ 1, // SmbusSignalSupported :1;
+ 0 // Reserved :21;
+ },
+ {0} // SlotDevicePath
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot2) = {
+ STRING_TOKEN(STR_MISC_SYSTEM_SLOT2), // SlotDesignation
+ EfiSlotTypePciExpress, // SlotType
+ EfiSlotDataBusWidth32Bit, // SlotDataBusWidth
+ EfiSlotUsageAvailable, // SlotUsage
+ EfiSlotLengthLong , // SlotLength
+ 1, // SlotId
+ { // SlotCharacteristics
+ 0, // CharacteristicsUnknown :1;
+ 0, // Provides50Volts :1;
+ 1, // Provides33Volts :1;
+ 0, // SharedSlot :1;
+ 0, // PcCard16Supported :1;
+ 0, // CardBusSupported :1;
+ 0, // ZoomVideoSupported :1;
+ 0, // ModemRingResumeSupported:1;
+ 1, // PmeSignalSupported :1;
+ 1, // HotPlugDevicesSupported :1;
+ 1, // SmbusSignalSupported :1;
+ 0 // Reserved :21;
+ },
+ {0} // SlotDevicePath
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot3) = {
+ STRING_TOKEN(STR_MISC_SYSTEM_SLOT3), // SlotDesignation
+ EfiSlotTypePciExpress, // SlotType
+ EfiSlotDataBusWidth32Bit, // SlotDataBusWidth
+ EfiSlotUsageAvailable, // SlotUsage
+ EfiSlotLengthLong , // SlotLength
+ 2, // SlotId
+ { // SlotCharacteristics
+ 0, // CharacteristicsUnknown :1;
+ 0, // Provides50Volts :1;
+ 1, // Provides33Volts :1;
+ 0, // SharedSlot :1;
+ 0, // PcCard16Supported :1;
+ 0, // CardBusSupported :1;
+ 0, // ZoomVideoSupported :1;
+ 0, // ModemRingResumeSupported:1;
+ 1, // PmeSignalSupported :1;
+ 1, // HotPlugDevicesSupported :1;
+ 1, // SmbusSignalSupported :1;
+ 0 // Reserved :21;
+ },
+ {0} // SlotDevicePath
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot4) = {
+ STRING_TOKEN(STR_MISC_SYSTEM_SLOT4), // SlotDesignation
+ EfiSlotTypePciExpress, // SlotType
+ EfiSlotDataBusWidth32Bit, // SlotDataBusWidth
+ EfiSlotUsageAvailable, // SlotUsage
+ EfiSlotLengthLong , // SlotLength
+ 2, // SlotId
+ { // SlotCharacteristics
+ 0, // CharacteristicsUnknown :1;
+ 0, // Provides50Volts :1;
+ 1, // Provides33Volts :1;
+ 0, // SharedSlot :1;
+ 0, // PcCard16Supported :1;
+ 0, // CardBusSupported :1;
+ 0, // ZoomVideoSupported :1;
+ 0, // ModemRingResumeSupported:1;
+ 1, // PmeSignalSupported :1;
+ 1, // HotPlugDevicesSupported :1;
+ 1, // SmbusSignalSupported :1;
+ 0 // Reserved :21;
+ },
+ {0} // SlotDevicePath
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot5) = {
+ STRING_TOKEN(STR_MISC_SYSTEM_SLOT5), // SlotDesignation
+ EfiSlotTypePciExpress, // SlotType
+ EfiSlotDataBusWidth32Bit, // SlotDataBusWidth
+ EfiSlotUsageAvailable, // SlotUsage
+ EfiSlotLengthLong , // SlotLength
+ 3, // SlotId
+ { // SlotCharacteristics
+ 0, // CharacteristicsUnknown :1;
+ 0, // Provides50Volts :1;
+ 1, // Provides33Volts :1;
+ 0, // SharedSlot :1;
+ 0, // PcCard16Supported :1;
+ 0, // CardBusSupported :1;
+ 0, // ZoomVideoSupported :1;
+ 0, // ModemRingResumeSupported:1;
+ 1, // PmeSignalSupported :1;
+ 1, // HotPlugDevicesSupported :1;
+ 1, // SmbusSignalSupported :1;
+ 0 // Reserved :21;
+ },
+ {0} // SlotDevicePath
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot6) = {
+ STRING_TOKEN(STR_MISC_SYSTEM_SLOT6), // SlotDesignation
+ EfiSlotTypePciExpress, // SlotType
+ EfiSlotDataBusWidth32Bit, // SlotDataBusWidth
+ EfiSlotUsageAvailable, // SlotUsage
+ EfiSlotLengthLong , // SlotLength
+ 3, // SlotId
+ { // SlotCharacteristics
+ 0, // CharacteristicsUnknown :1;
+ 0, // Provides50Volts :1;
+ 1, // Provides33Volts :1;
+ 0, // SharedSlot :1;
+ 0, // PcCard16Supported :1;
+ 0, // CardBusSupported :1;
+ 0, // ZoomVideoSupported :1;
+ 0, // ModemRingResumeSupported:1;
+ 1, // PmeSignalSupported :1;
+ 1, // HotPlugDevicesSupported :1;
+ 1, // SmbusSignalSupported :1;
+ 0 // Reserved :21;
+ },
+ {0} // SlotDevicePath
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot7) = {
+ STRING_TOKEN(STR_MISC_SYSTEM_SLOT7), // SlotDesignation
+ EfiSlotTypePciExpress, // SlotType
+ EfiSlotDataBusWidth32Bit, // SlotDataBusWidth
+ EfiSlotUsageAvailable, // SlotUsage
+ EfiSlotLengthLong , // SlotLength
+ 3, // SlotId
+ { // SlotCharacteristics
+ 0, // CharacteristicsUnknown :1;
+ 0, // Provides50Volts :1;
+ 1, // Provides33Volts :1;
+ 0, // SharedSlot :1;
+ 0, // PcCard16Supported :1;
+ 0, // CardBusSupported :1;
+ 0, // ZoomVideoSupported :1;
+ 0, // ModemRingResumeSupported:1;
+ 1, // PmeSignalSupported :1;
+ 1, // HotPlugDevicesSupported :1;
+ 1, // SmbusSignalSupported :1;
+ 0 // Reserved :21;
+ },
+ {0} // SlotDevicePath
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot8) = {
+ STRING_TOKEN(STR_MISC_SYSTEM_SLOT8), // SlotDesignation
+ EfiSlotTypePciExpress, // SlotType
+ EfiSlotDataBusWidth32Bit, // SlotDataBusWidth
+ EfiSlotUsageAvailable, // SlotUsage
+ EfiSlotLengthLong , // SlotLength
+ 3, // SlotId
+ { // SlotCharacteristics
+ 0, // CharacteristicsUnknown :1;
+ 0, // Provides50Volts :1;
+ 1, // Provides33Volts :1;
+ 0, // SharedSlot :1;
+ 0, // PcCard16Supported :1;
+ 0, // CardBusSupported :1;
+ 0, // ZoomVideoSupported :1;
+ 0, // ModemRingResumeSupported:1;
+ 1, // PmeSignalSupported :1;
+ 1, // HotPlugDevicesSupported :1;
+ 1, // SmbusSignalSupported :1;
+ 0 // Reserved :21;
+ },
+ {0} // SlotDevicePath
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot9) = {
+ STRING_TOKEN(STR_MISC_SYSTEM_SLOT9), // SlotDesignation
+ EfiSlotTypeUnknown, // SlotType
+ EfiSlotDataBusWidthUnknown, // SlotDataBusWidth
+ EfiSlotUsageUnknown, // SlotUsage
+ EfiSlotLengthUnknown , // SlotLength
+ 0, // SlotId
+ { // SlotCharacteristics
+ 0, // CharacteristicsUnknown :1;
+ 0, // Provides50Volts :1;
+ 1, // Provides33Volts :1;
+ 0, // SharedSlot :1;
+ 0, // PcCard16Supported :1;
+ 0, // CardBusSupported :1;
+ 0, // ZoomVideoSupported :1;
+ 0, // ModemRingResumeSupported:1;
+ 1, // PmeSignalSupported :1;
+ 1, // HotPlugDevicesSupported :1;
+ 1, // SmbusSignalSupported :1;
+ 0 // Reserved :21;
+ },
+ {0} // SlotDevicePath
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot10) = {
+ STRING_TOKEN(STR_MISC_SYSTEM_SLOT10), // SlotDesignation
+ EfiSlotTypeUnknown, // SlotType
+ EfiSlotDataBusWidthUnknown, // SlotDataBusWidth
+ EfiSlotUsageUnknown, // SlotUsage
+ EfiSlotLengthUnknown , // SlotLength
+ 0, // SlotId
+ { // SlotCharacteristics
+ 0, // CharacteristicsUnknown :1;
+ 0, // Provides50Volts :1;
+ 1, // Provides33Volts :1;
+ 0, // SharedSlot :1;
+ 0, // PcCard16Supported :1;
+ 0, // CardBusSupported :1;
+ 0, // ZoomVideoSupported :1;
+ 0, // ModemRingResumeSupported:1;
+ 1, // PmeSignalSupported :1;
+ 1, // HotPlugDevicesSupported :1;
+ 1, // SmbusSignalSupported :1;
+ 0 // Reserved :21;
+ },
+ {0} // SlotDevicePath
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot11) = {
+ STRING_TOKEN(STR_MISC_SYSTEM_SLOT11), // SlotDesignation
+ EfiSlotTypeUnknown, // SlotType
+ EfiSlotDataBusWidthUnknown, // SlotDataBusWidth
+ EfiSlotUsageUnknown, // SlotUsage
+ EfiSlotLengthUnknown , // SlotLength
+ 0, // SlotId
+ { // SlotCharacteristics
+ 0, // CharacteristicsUnknown :1;
+ 0, // Provides50Volts :1;
+ 1, // Provides33Volts :1;
+ 0, // SharedSlot :1;
+ 0, // PcCard16Supported :1;
+ 0, // CardBusSupported :1;
+ 0, // ZoomVideoSupported :1;
+ 0, // ModemRingResumeSupported:1;
+ 1, // PmeSignalSupported :1;
+ 1, // HotPlugDevicesSupported :1;
+ 1, // SmbusSignalSupported :1;
+ 0 // Reserved :21;
+ },
+ {0} // SlotDevicePath
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot12) = {
+ STRING_TOKEN(STR_MISC_SYSTEM_SLOT12), // SlotDesignation
+ EfiSlotTypeUnknown, // SlotType
+ EfiSlotDataBusWidthUnknown, // SlotDataBusWidth
+ EfiSlotUsageUnknown, // SlotUsage
+ EfiSlotLengthUnknown , // SlotLength
+ 0, // SlotId
+ { // SlotCharacteristics
+ 0, // CharacteristicsUnknown :1;
+ 0, // Provides50Volts :1;
+ 1, // Provides33Volts :1;
+ 0, // SharedSlot :1;
+ 0, // PcCard16Supported :1;
+ 0, // CardBusSupported :1;
+ 0, // ZoomVideoSupported :1;
+ 0, // ModemRingResumeSupported:1;
+ 1, // PmeSignalSupported :1;
+ 1, // HotPlugDevicesSupported :1;
+ 1, // SmbusSignalSupported :1;
+ 0 // Reserved :21;
+ },
+ {0} // SlotDevicePath
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot13) = {
+ STRING_TOKEN(STR_MISC_SYSTEM_SLOT13), // SlotDesignation
+ EfiSlotTypeUnknown, // SlotType
+ EfiSlotDataBusWidthUnknown, // SlotDataBusWidth
+ EfiSlotUsageUnknown, // SlotUsage
+ EfiSlotLengthUnknown , // SlotLength
+ 0, // SlotId
+ { // SlotCharacteristics
+ 0, // CharacteristicsUnknown :1;
+ 0, // Provides50Volts :1;
+ 1, // Provides33Volts :1;
+ 0, // SharedSlot :1;
+ 0, // PcCard16Supported :1;
+ 0, // CardBusSupported :1;
+ 0, // ZoomVideoSupported :1;
+ 0, // ModemRingResumeSupported:1;
+ 1, // PmeSignalSupported :1;
+ 1, // HotPlugDevicesSupported :1;
+ 1, // SmbusSignalSupported :1;
+ 0 // Reserved :21;
+ },
+ {0} // SlotDevicePath
+};
+
+MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot14) = {
+ STRING_TOKEN(STR_MISC_SYSTEM_SLOT14), // SlotDesignation
+ EfiSlotTypeUnknown, // SlotType
+ EfiSlotDataBusWidthUnknown, // SlotDataBusWidth
+ EfiSlotUsageUnknown, // SlotUsage
+ EfiSlotLengthUnknown , // SlotLength
+ 0, // SlotId
+ { // SlotCharacteristics
+ 0, // CharacteristicsUnknown :1;
+ 0, // Provides50Volts :1;
+ 1, // Provides33Volts :1;
+ 0, // SharedSlot :1;
+ 0, // PcCard16Supported :1;
+ 0, // CardBusSupported :1;
+ 0, // ZoomVideoSupported :1;
+ 0, // ModemRingResumeSupported:1;
+ 1, // PmeSignalSupported :1;
+ 1, // HotPlugDevicesSupported :1;
+ 1, // SmbusSignalSupported :1;
+ 0 // Reserved :21;
+ },
+ {0} // SlotDevicePath
+};
+
+
diff --git a/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemSlotDesignationFunction.c b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemSlotDesignationFunction.c
new file mode 100644
index 0000000000..79fa509405
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemSlotDesignationFunction.c
@@ -0,0 +1,291 @@
+/** @file
+BIOS system slot designator information boot time changes.
+SMBIOS type 9.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+
+MiscSystemSlotDesignatorFunction.c
+
+**/
+
+
+#include "CommonHeader.h"
+
+#include "SmbiosMisc.h"
+
+//
+//
+//
+
+MISC_SMBIOS_DATA_TABLE_EXTERNS (EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot1);
+MISC_SMBIOS_DATA_TABLE_EXTERNS (EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot2);
+MISC_SMBIOS_DATA_TABLE_EXTERNS (EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot3);
+MISC_SMBIOS_DATA_TABLE_EXTERNS (EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot4);
+MISC_SMBIOS_DATA_TABLE_EXTERNS (EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot5);
+MISC_SMBIOS_DATA_TABLE_EXTERNS (EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot6);
+MISC_SMBIOS_DATA_TABLE_EXTERNS (EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot7);
+MISC_SMBIOS_DATA_TABLE_EXTERNS (EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot8);
+MISC_SMBIOS_DATA_TABLE_EXTERNS (EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot9);
+MISC_SMBIOS_DATA_TABLE_EXTERNS (EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot10);
+MISC_SMBIOS_DATA_TABLE_EXTERNS (EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot11);
+MISC_SMBIOS_DATA_TABLE_EXTERNS (EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot12);
+MISC_SMBIOS_DATA_TABLE_EXTERNS (EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot13);
+MISC_SMBIOS_DATA_TABLE_EXTERNS (EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot14);
+
+EFI_MISC_SYSTEM_SLOT_DESIGNATION *mMiscSlotArray[SMBIOS_SYSTEM_SLOT_MAX_NUM] =
+{
+ MISC_SMBIOS_DATA_TABLE_POINTER (MiscSystemSlot1),
+ MISC_SMBIOS_DATA_TABLE_POINTER (MiscSystemSlot2),
+ MISC_SMBIOS_DATA_TABLE_POINTER (MiscSystemSlot3),
+ MISC_SMBIOS_DATA_TABLE_POINTER (MiscSystemSlot4),
+ MISC_SMBIOS_DATA_TABLE_POINTER (MiscSystemSlot5),
+ MISC_SMBIOS_DATA_TABLE_POINTER (MiscSystemSlot6),
+ MISC_SMBIOS_DATA_TABLE_POINTER (MiscSystemSlot7),
+ MISC_SMBIOS_DATA_TABLE_POINTER (MiscSystemSlot8),
+ MISC_SMBIOS_DATA_TABLE_POINTER (MiscSystemSlot9),
+ MISC_SMBIOS_DATA_TABLE_POINTER (MiscSystemSlot10),
+ MISC_SMBIOS_DATA_TABLE_POINTER (MiscSystemSlot11),
+ MISC_SMBIOS_DATA_TABLE_POINTER (MiscSystemSlot12),
+ MISC_SMBIOS_DATA_TABLE_POINTER (MiscSystemSlot13),
+ MISC_SMBIOS_DATA_TABLE_POINTER (MiscSystemSlot14),
+};
+
+BOOLEAN PcdMiscSlotIsInit = FALSE;
+SMBIOS_SLOT_COFNIG SMBIOSlotConfig = {0};
+
+/**
+ Get Misc Slot Configuration information from PCD
+ @param SMBIOSPortConnector Pointer to SMBIOSPortConnector table.
+
+**/
+
+VOID
+GetMiscSLotConfigFromPcd ()
+{
+ //
+ // Type 9
+ //
+ SMBIOSlotConfig.SMBIOSSystemSlotNumber = PcdGet8 (PcdSMBIOSSystemSlotNumber);
+ AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSSystemSlot1Designation), SMBIOSlotConfig.SMBIOSSystemSlot[0].SlotDesignation);
+ SMBIOSlotConfig.SMBIOSSystemSlot[0].SlotType = PcdGet8(PcdSMBIOSSystemSlot1Type);
+ SMBIOSlotConfig.SMBIOSSystemSlot[0].SlotDataBusWidth = PcdGet8(PcdSMBIOSSystemSlot1DataBusWidth);
+ SMBIOSlotConfig.SMBIOSSystemSlot[0].SlotUsage = PcdGet8(PcdSMBIOSSystemSlot1Usage);
+ SMBIOSlotConfig.SMBIOSSystemSlot[0].SlotLength = PcdGet8(PcdSMBIOSSystemSlot1Length);
+ SMBIOSlotConfig.SMBIOSSystemSlot[0].SlotId = PcdGet16(PcdSMBIOSSystemSlot1Id);
+ SMBIOSlotConfig.SMBIOSSystemSlot[0].SlotCharacteristics = PcdGet32(PcdSMBIOSSystemSlot1Characteristics);
+
+ AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSSystemSlot2Designation), SMBIOSlotConfig.SMBIOSSystemSlot[1].SlotDesignation);
+ SMBIOSlotConfig.SMBIOSSystemSlot[1].SlotType = PcdGet8(PcdSMBIOSSystemSlot2Type);
+ SMBIOSlotConfig.SMBIOSSystemSlot[1].SlotDataBusWidth = PcdGet8(PcdSMBIOSSystemSlot2DataBusWidth);
+ SMBIOSlotConfig.SMBIOSSystemSlot[1].SlotUsage = PcdGet8(PcdSMBIOSSystemSlot2Usage);
+ SMBIOSlotConfig.SMBIOSSystemSlot[1].SlotLength = PcdGet8(PcdSMBIOSSystemSlot2Length);
+ SMBIOSlotConfig.SMBIOSSystemSlot[1].SlotId = PcdGet16(PcdSMBIOSSystemSlot2Id);
+ SMBIOSlotConfig.SMBIOSSystemSlot[1].SlotCharacteristics = PcdGet32(PcdSMBIOSSystemSlot2Characteristics);
+
+ AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSSystemSlot3Designation), SMBIOSlotConfig.SMBIOSSystemSlot[2].SlotDesignation);
+ SMBIOSlotConfig.SMBIOSSystemSlot[2].SlotType = PcdGet8(PcdSMBIOSSystemSlot3Type);
+ SMBIOSlotConfig.SMBIOSSystemSlot[2].SlotDataBusWidth = PcdGet8(PcdSMBIOSSystemSlot3DataBusWidth);
+ SMBIOSlotConfig.SMBIOSSystemSlot[2].SlotUsage = PcdGet8(PcdSMBIOSSystemSlot3Usage);
+ SMBIOSlotConfig.SMBIOSSystemSlot[2].SlotLength = PcdGet8(PcdSMBIOSSystemSlot3Length);
+ SMBIOSlotConfig.SMBIOSSystemSlot[2].SlotId = PcdGet16(PcdSMBIOSSystemSlot3Id);
+ SMBIOSlotConfig.SMBIOSSystemSlot[2].SlotCharacteristics = PcdGet32(PcdSMBIOSSystemSlot3Characteristics);
+
+ AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSSystemSlot4Designation), SMBIOSlotConfig.SMBIOSSystemSlot[3].SlotDesignation);
+ SMBIOSlotConfig.SMBIOSSystemSlot[3].SlotType = PcdGet8(PcdSMBIOSSystemSlot4Type);
+ SMBIOSlotConfig.SMBIOSSystemSlot[3].SlotDataBusWidth = PcdGet8(PcdSMBIOSSystemSlot4DataBusWidth);
+ SMBIOSlotConfig.SMBIOSSystemSlot[3].SlotUsage = PcdGet8(PcdSMBIOSSystemSlot4Usage);
+ SMBIOSlotConfig.SMBIOSSystemSlot[3].SlotLength = PcdGet8(PcdSMBIOSSystemSlot4Length);
+ SMBIOSlotConfig.SMBIOSSystemSlot[3].SlotId = PcdGet16(PcdSMBIOSSystemSlot4Id);
+ SMBIOSlotConfig.SMBIOSSystemSlot[3].SlotCharacteristics = PcdGet32(PcdSMBIOSSystemSlot4Characteristics);
+
+ AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSSystemSlot5Designation), SMBIOSlotConfig.SMBIOSSystemSlot[4].SlotDesignation);
+ SMBIOSlotConfig.SMBIOSSystemSlot[4].SlotType = PcdGet8(PcdSMBIOSSystemSlot5Type);
+ SMBIOSlotConfig.SMBIOSSystemSlot[4].SlotDataBusWidth = PcdGet8(PcdSMBIOSSystemSlot5DataBusWidth);
+ SMBIOSlotConfig.SMBIOSSystemSlot[4].SlotUsage = PcdGet8(PcdSMBIOSSystemSlot5Usage);
+ SMBIOSlotConfig.SMBIOSSystemSlot[4].SlotLength = PcdGet8(PcdSMBIOSSystemSlot5Length);
+ SMBIOSlotConfig.SMBIOSSystemSlot[4].SlotId = PcdGet16(PcdSMBIOSSystemSlot5Id);
+ SMBIOSlotConfig.SMBIOSSystemSlot[4].SlotCharacteristics = PcdGet32(PcdSMBIOSSystemSlot5Characteristics);
+
+ AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSSystemSlot6Designation), SMBIOSlotConfig.SMBIOSSystemSlot[5].SlotDesignation);
+ SMBIOSlotConfig.SMBIOSSystemSlot[5].SlotType = PcdGet8(PcdSMBIOSSystemSlot6Type);
+ SMBIOSlotConfig.SMBIOSSystemSlot[5].SlotDataBusWidth = PcdGet8(PcdSMBIOSSystemSlot6DataBusWidth);
+ SMBIOSlotConfig.SMBIOSSystemSlot[5].SlotUsage = PcdGet8(PcdSMBIOSSystemSlot6Usage);
+ SMBIOSlotConfig.SMBIOSSystemSlot[5].SlotLength = PcdGet8(PcdSMBIOSSystemSlot6Length);
+ SMBIOSlotConfig.SMBIOSSystemSlot[5].SlotId = PcdGet16(PcdSMBIOSSystemSlot6Id);
+ SMBIOSlotConfig.SMBIOSSystemSlot[5].SlotCharacteristics = PcdGet32(PcdSMBIOSSystemSlot6Characteristics);
+
+ AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSSystemSlot7Designation), SMBIOSlotConfig.SMBIOSSystemSlot[6].SlotDesignation);
+ SMBIOSlotConfig.SMBIOSSystemSlot[6].SlotType = PcdGet8(PcdSMBIOSSystemSlot7Type);
+ SMBIOSlotConfig.SMBIOSSystemSlot[6].SlotDataBusWidth = PcdGet8(PcdSMBIOSSystemSlot7DataBusWidth);
+ SMBIOSlotConfig.SMBIOSSystemSlot[6].SlotUsage = PcdGet8(PcdSMBIOSSystemSlot7Usage);
+ SMBIOSlotConfig.SMBIOSSystemSlot[6].SlotLength = PcdGet8(PcdSMBIOSSystemSlot7Length);
+ SMBIOSlotConfig.SMBIOSSystemSlot[6].SlotId = PcdGet16(PcdSMBIOSSystemSlot7Id);
+ SMBIOSlotConfig.SMBIOSSystemSlot[6].SlotCharacteristics = PcdGet32(PcdSMBIOSSystemSlot7Characteristics);
+
+ AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSSystemSlot8Designation), SMBIOSlotConfig.SMBIOSSystemSlot[7].SlotDesignation);
+ SMBIOSlotConfig.SMBIOSSystemSlot[7].SlotType = PcdGet8(PcdSMBIOSSystemSlot8Type);
+ SMBIOSlotConfig.SMBIOSSystemSlot[7].SlotDataBusWidth = PcdGet8(PcdSMBIOSSystemSlot8DataBusWidth);
+ SMBIOSlotConfig.SMBIOSSystemSlot[7].SlotUsage = PcdGet8(PcdSMBIOSSystemSlot8Usage);
+ SMBIOSlotConfig.SMBIOSSystemSlot[7].SlotLength = PcdGet8(PcdSMBIOSSystemSlot8Length);
+ SMBIOSlotConfig.SMBIOSSystemSlot[7].SlotId = PcdGet16(PcdSMBIOSSystemSlot8Id);
+ SMBIOSlotConfig.SMBIOSSystemSlot[7].SlotCharacteristics = PcdGet32(PcdSMBIOSSystemSlot8Characteristics);
+
+ AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSSystemSlot9Designation), SMBIOSlotConfig.SMBIOSSystemSlot[8].SlotDesignation);
+ SMBIOSlotConfig.SMBIOSSystemSlot[8].SlotType = PcdGet8(PcdSMBIOSSystemSlot9Type);
+ SMBIOSlotConfig.SMBIOSSystemSlot[8].SlotDataBusWidth = PcdGet8(PcdSMBIOSSystemSlot9DataBusWidth);
+ SMBIOSlotConfig.SMBIOSSystemSlot[8].SlotUsage = PcdGet8(PcdSMBIOSSystemSlot9Usage);
+ SMBIOSlotConfig.SMBIOSSystemSlot[8].SlotLength = PcdGet8(PcdSMBIOSSystemSlot9Length);
+ SMBIOSlotConfig.SMBIOSSystemSlot[8].SlotId = PcdGet16(PcdSMBIOSSystemSlot9Id);
+ SMBIOSlotConfig.SMBIOSSystemSlot[8].SlotCharacteristics = PcdGet32(PcdSMBIOSSystemSlot9Characteristics);
+
+ AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSSystemSlot10Designation), SMBIOSlotConfig.SMBIOSSystemSlot[9].SlotDesignation);
+ SMBIOSlotConfig.SMBIOSSystemSlot[9].SlotType = PcdGet8(PcdSMBIOSSystemSlot10Type);
+ SMBIOSlotConfig.SMBIOSSystemSlot[9].SlotDataBusWidth = PcdGet8(PcdSMBIOSSystemSlot10DataBusWidth);
+ SMBIOSlotConfig.SMBIOSSystemSlot[9].SlotUsage = PcdGet8(PcdSMBIOSSystemSlot10Usage);
+ SMBIOSlotConfig.SMBIOSSystemSlot[9].SlotLength = PcdGet8(PcdSMBIOSSystemSlot10Length);
+ SMBIOSlotConfig.SMBIOSSystemSlot[9].SlotId = PcdGet16(PcdSMBIOSSystemSlot10Id);
+ SMBIOSlotConfig.SMBIOSSystemSlot[9].SlotCharacteristics = PcdGet32(PcdSMBIOSSystemSlot10Characteristics);
+
+ AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSSystemSlot11Designation), SMBIOSlotConfig.SMBIOSSystemSlot[10].SlotDesignation);
+ SMBIOSlotConfig.SMBIOSSystemSlot[10].SlotType = PcdGet8(PcdSMBIOSSystemSlot11Type);
+ SMBIOSlotConfig.SMBIOSSystemSlot[10].SlotDataBusWidth = PcdGet8(PcdSMBIOSSystemSlot11DataBusWidth);
+ SMBIOSlotConfig.SMBIOSSystemSlot[10].SlotUsage = PcdGet8(PcdSMBIOSSystemSlot11Usage);
+ SMBIOSlotConfig.SMBIOSSystemSlot[10].SlotLength = PcdGet8(PcdSMBIOSSystemSlot11Length);
+ SMBIOSlotConfig.SMBIOSSystemSlot[10].SlotId = PcdGet16(PcdSMBIOSSystemSlot11Id);
+ SMBIOSlotConfig.SMBIOSSystemSlot[10].SlotCharacteristics = PcdGet32(PcdSMBIOSSystemSlot11Characteristics);
+
+ AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSSystemSlot12Designation), SMBIOSlotConfig.SMBIOSSystemSlot[11].SlotDesignation);
+ SMBIOSlotConfig.SMBIOSSystemSlot[11].SlotType = PcdGet8(PcdSMBIOSSystemSlot12Type);
+ SMBIOSlotConfig.SMBIOSSystemSlot[11].SlotDataBusWidth = PcdGet8(PcdSMBIOSSystemSlot12DataBusWidth);
+ SMBIOSlotConfig.SMBIOSSystemSlot[11].SlotUsage = PcdGet8(PcdSMBIOSSystemSlot12Usage);
+ SMBIOSlotConfig.SMBIOSSystemSlot[11].SlotLength = PcdGet8(PcdSMBIOSSystemSlot12Length);
+ SMBIOSlotConfig.SMBIOSSystemSlot[11].SlotId = PcdGet16(PcdSMBIOSSystemSlot12Id);
+ SMBIOSlotConfig.SMBIOSSystemSlot[11].SlotCharacteristics = PcdGet32(PcdSMBIOSSystemSlot12Characteristics);
+
+ AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSSystemSlot13Designation), SMBIOSlotConfig.SMBIOSSystemSlot[12].SlotDesignation);
+ SMBIOSlotConfig.SMBIOSSystemSlot[12].SlotType = PcdGet8(PcdSMBIOSSystemSlot13Type);
+ SMBIOSlotConfig.SMBIOSSystemSlot[12].SlotDataBusWidth = PcdGet8(PcdSMBIOSSystemSlot13DataBusWidth);
+ SMBIOSlotConfig.SMBIOSSystemSlot[12].SlotUsage = PcdGet8(PcdSMBIOSSystemSlot13Usage);
+ SMBIOSlotConfig.SMBIOSSystemSlot[12].SlotLength = PcdGet8(PcdSMBIOSSystemSlot13Length);
+ SMBIOSlotConfig.SMBIOSSystemSlot[12].SlotId = PcdGet16(PcdSMBIOSSystemSlot13Id);
+ SMBIOSlotConfig.SMBIOSSystemSlot[12].SlotCharacteristics = PcdGet32(PcdSMBIOSSystemSlot13Characteristics);
+
+ AsciiStrToUnicodeStr ((CHAR8 *) PcdGetPtr(PcdSMBIOSSystemSlot14Designation), SMBIOSlotConfig.SMBIOSSystemSlot[13].SlotDesignation);
+ SMBIOSlotConfig.SMBIOSSystemSlot[13].SlotType = PcdGet8(PcdSMBIOSSystemSlot14Type);
+ SMBIOSlotConfig.SMBIOSSystemSlot[13].SlotDataBusWidth = PcdGet8(PcdSMBIOSSystemSlot14DataBusWidth);
+ SMBIOSlotConfig.SMBIOSSystemSlot[13].SlotUsage = PcdGet8(PcdSMBIOSSystemSlot14Usage);
+ SMBIOSlotConfig.SMBIOSSystemSlot[13].SlotLength = PcdGet8(PcdSMBIOSSystemSlot14Length);
+ SMBIOSlotConfig.SMBIOSSystemSlot[13].SlotId = PcdGet16(PcdSMBIOSSystemSlot14Id);
+ SMBIOSlotConfig.SMBIOSSystemSlot[13].SlotCharacteristics = PcdGet32(PcdSMBIOSSystemSlot14Characteristics);
+}
+/**
+ This function makes boot time changes to the contents of the
+ MiscSystemSlotDesignator structure (Type 9).
+
+ @param RecordData Pointer to copy of RecordData from the Data Table.
+
+ @retval EFI_SUCCESS All parameters were valid.
+ @retval EFI_UNSUPPORTED Unexpected RecordType value.
+ @retval EFI_INVALID_PARAMETER Invalid parameter was found.
+
+**/
+MISC_SMBIOS_TABLE_FUNCTION(MiscSystemSlotDesignator)
+{
+ CHAR8 *OptionalStrStart;
+ UINTN SlotDesignationStrLen;
+ EFI_STATUS Status;
+ EFI_STRING SlotDesignation;
+ STRING_REF TokenToUpdate;
+ STRING_REF TokenToGet;
+ SMBIOS_TABLE_TYPE9 *SmbiosRecord;
+ EFI_SMBIOS_HANDLE SmbiosHandle;
+ EFI_MISC_SYSTEM_SLOT_DESIGNATION* ForType9InputData;
+ UINT8 Index;
+
+ ForType9InputData = (EFI_MISC_SYSTEM_SLOT_DESIGNATION *)RecordData;
+
+ TokenToGet = 0;
+
+ //
+ // First check for invalid parameters.
+ //
+ if (RecordData == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (!PcdMiscSlotIsInit) {
+ GetMiscSLotConfigFromPcd ();
+ PcdMiscSlotIsInit = TRUE;
+ }
+
+ for (Index = 0; Index < SMBIOS_SYSTEM_SLOT_MAX_NUM; Index++) {
+ if (ForType9InputData->SlotDesignation == (mMiscSlotArray[Index])->SlotDesignation) {
+ //DEBUG ((EFI_D_ERROR, "Found slot Data %d : ", Index));
+ break;
+ }
+ }
+ if (Index >= SMBIOSlotConfig.SMBIOSSystemSlotNumber) {
+ return EFI_SUCCESS;
+ }
+
+ if (Index >= SMBIOS_SYSTEM_SLOT_MAX_NUM) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ SlotDesignation = SMBIOSlotConfig.SMBIOSSystemSlot[Index].SlotDesignation;
+ TokenToGet = STRING_TOKEN ((mMiscSlotArray[Index])->SlotDesignation);
+
+ if (StrLen (SlotDesignation) > 0) {
+ TokenToUpdate = STRING_TOKEN ((mMiscSlotArray[Index])->SlotDesignation);
+ HiiSetString (mHiiHandle, TokenToUpdate, SlotDesignation, NULL);
+ }
+
+ SlotDesignation = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL);
+ SlotDesignationStrLen = StrLen(SlotDesignation);
+ if (SlotDesignationStrLen > SMBIOS_STRING_MAX_LENGTH) {
+ return EFI_UNSUPPORTED;
+ }
+ //
+ // Two zeros following the last string.
+ //
+ SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE9) + SlotDesignationStrLen + 1 + 1);
+ ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE9) +SlotDesignationStrLen + 1 + 1);
+
+ SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_SYSTEM_SLOTS;
+ SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE9);
+ SmbiosRecord->Hdr.Handle = 0;
+ SmbiosRecord->SlotDesignation = 1;
+ SmbiosRecord->SlotType = SMBIOSlotConfig.SMBIOSSystemSlot[Index].SlotType;
+ SmbiosRecord->SlotDataBusWidth = SMBIOSlotConfig.SMBIOSSystemSlot[Index].SlotDataBusWidth;
+ SmbiosRecord->CurrentUsage = SMBIOSlotConfig.SMBIOSSystemSlot[Index].SlotUsage;
+ SmbiosRecord->SlotLength = SMBIOSlotConfig.SMBIOSSystemSlot[Index].SlotLength;
+ SmbiosRecord->SlotID = SMBIOSlotConfig.SMBIOSSystemSlot[Index].SlotId;
+ *(UINT16 *)&SmbiosRecord->SlotCharacteristics1 = (UINT16)(SMBIOSlotConfig.SMBIOSSystemSlot[Index].SlotCharacteristics);
+
+ //
+ // Slot Characteristics
+ //
+ OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
+ UnicodeStrToAsciiStr(SlotDesignation, OptionalStrStart);
+ //
+ // Now we have got the full smbios record, call smbios protocol to add this record.
+ //
+ SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+ Status = Smbios-> Add(
+ Smbios,
+ NULL,
+ &SmbiosHandle,
+ (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
+ );
+ FreePool(SmbiosRecord);
+ return Status;
+}
diff --git a/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemSlotOnboardDevices.uni b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemSlotOnboardDevices.uni
new file mode 100644
index 0000000000..e8490f9982
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/MiscSystemSlotOnboardDevices.uni
@@ -0,0 +1,29 @@
+// /** @file
+// System Slot onboard devices
+//
+// Copyright (c) 2013-2015 Intel Corporation.
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+//
+// **/
+/=#
+
+
+
+#string STR_MISC_SYSTEM_SLOT_P64_B1 #language en-US "P64B1"
+#string STR_MISC_SYSTEM_SLOT_P64_B2 #language en-US "P64B2"
+#string STR_MISC_SYSTEM_SLOT_P64_B3 #language en-US "P64B3"
+#string STR_MISC_SYSTEM_SLOT_P64_C1 #language en-US "P64C1"
+#string STR_MISC_SYSTEM_SLOT_P64_C2 #language en-US "P64C2"
+#string STR_MISC_SYSTEM_SLOT_P64_C3 #language en-US "P64C3"
+
+
+
+
diff --git a/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMisc.h b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMisc.h
new file mode 100644
index 0000000000..26b71d8e46
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMisc.h
@@ -0,0 +1,143 @@
+/** @file
+Header file for the SmbiosMisc Driver.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+
+**/
+
+#ifndef _SMBIOS_MISC_H
+#define _SMBIOS_MISC_H
+
+#include "MiscDevicePath.h"
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/PrintLib.h>
+
+///
+/// Reference SMBIOS 2.6, chapter 3.1.3.
+/// Each text string is limited to 64 significant characters due to system MIF limitations.
+///
+#define SMBIOS_STRING_MAX_LENGTH 64
+#define SMBIOS_PORT_CONNECTOR_MAX_NUM 14
+
+typedef struct {
+ CHAR16 PortInternalConnectorDesignator[SMBIOS_STRING_MAX_LENGTH];
+ CHAR16 PortExternalConnectorDesignator[SMBIOS_STRING_MAX_LENGTH];
+ UINT8 PortInternalConnectorType;
+ UINT8 PortExternalConnectorType;
+ UINT8 PortType;
+} SMBIOS_PORT_CONNECTOR_DESIGNATOR;
+
+typedef struct {
+ UINT8 SMBIOSConnectorNumber;
+ SMBIOS_PORT_CONNECTOR_DESIGNATOR SMBIOSPortConnector[SMBIOS_PORT_CONNECTOR_MAX_NUM];
+} SMBIOS_PORT_CONNECTOR_DESIGNATOR_COFNIG;
+
+#define SMBIOS_SYSTEM_SLOT_MAX_NUM 14
+
+typedef struct {
+ CHAR16 SlotDesignation[SMBIOS_STRING_MAX_LENGTH];
+ UINT8 SlotType;
+ UINT8 SlotDataBusWidth;
+ UINT8 SlotUsage;
+ UINT8 SlotLength;
+ UINT16 SlotId;
+ UINT32 SlotCharacteristics;
+} SMBIOS_SLOT_DESIGNATION;
+
+typedef struct {
+ UINT8 SMBIOSSystemSlotNumber;
+ SMBIOS_SLOT_DESIGNATION SMBIOSSystemSlot[SMBIOS_SYSTEM_SLOT_MAX_NUM];
+} SMBIOS_SLOT_COFNIG;
+
+//
+// Data table entry update function.
+//
+typedef EFI_STATUS (EFIAPI EFI_MISC_SMBIOS_DATA_FUNCTION) (
+ IN VOID *RecordData,
+ IN EFI_SMBIOS_PROTOCOL *Smbios
+ );
+
+
+//
+// Data table entry definition.
+//
+typedef struct {
+ //
+ // intermediat input data for SMBIOS record
+ //
+ VOID *RecordData;
+ EFI_MISC_SMBIOS_DATA_FUNCTION *Function;
+} EFI_MISC_SMBIOS_DATA_TABLE;
+
+//
+// Data Table extern definitions.
+//
+#define MISC_SMBIOS_DATA_TABLE_POINTER(NAME1) \
+ & NAME1 ## Data
+
+//
+// Data Table extern definitions.
+//
+#define MISC_SMBIOS_DATA_TABLE_EXTERNS(NAME1, NAME2) \
+extern NAME1 NAME2 ## Data
+
+//
+// Data and function Table extern definitions.
+//
+#define MISC_SMBIOS_TABLE_EXTERNS(NAME1, NAME2, NAME3) \
+extern NAME1 NAME2 ## Data; \
+extern EFI_MISC_SMBIOS_DATA_FUNCTION NAME3 ## Function
+
+
+//
+// Data Table entries
+//
+
+#define MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(NAME1, NAME2) \
+{ \
+ & NAME1 ## Data, \
+ & NAME2 ## Function \
+}
+
+
+//
+// Global definition macros.
+//
+#define MISC_SMBIOS_TABLE_DATA(NAME1, NAME2) \
+ NAME1 NAME2 ## Data
+
+#define MISC_SMBIOS_TABLE_FUNCTION(NAME2) \
+ EFI_STATUS EFIAPI NAME2 ## Function( \
+ IN VOID *RecordData, \
+ IN EFI_SMBIOS_PROTOCOL *Smbios \
+ )
+
+
+// Data Table Array
+//
+extern EFI_MISC_SMBIOS_DATA_TABLE mSmbiosMiscDataTable[];
+
+//
+// Data Table Array Entries
+//
+extern UINTN mSmbiosMiscDataTableEntries;
+extern EFI_HII_HANDLE mHiiHandle;
+//
+// Prototypes
+//
+EFI_STATUS
+PiSmbiosMiscEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+#endif
diff --git a/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMiscDataTable.c b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMiscDataTable.c
new file mode 100644
index 0000000000..ed88295465
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMiscDataTable.c
@@ -0,0 +1,115 @@
+/** @file
+This driver parses the mSmbiosMiscDataTable structure and reports
+any generated data using SMBIOS protocol.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+
+**/
+
+
+#include "CommonHeader.h"
+
+#include "SmbiosMisc.h"
+
+
+//
+// External definitions referenced by Data Table entries.
+//
+
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_BIOS_VENDOR, MiscBiosVendor, MiscBiosVendor);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_SYSTEM_MANUFACTURER, MiscSystemManufacturer, MiscSystemManufacturer);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_SYSTEM_MANUFACTURER, MiscBaseBoardManufacturer, MiscBaseBoardManufacturer);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_CHASSIS_MANUFACTURER, MiscChassisManufacturer, MiscChassisManufacturer);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_BOOT_INFORMATION_STATUS, MiscBootInfoStatus, MiscBootInfoStatus);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_NUMBER_OF_INSTALLABLE_LANGUAGES, NumberOfInstallableLanguages, NumberOfInstallableLanguages);
+MISC_SMBIOS_TABLE_EXTERNS (EFI_MISC_SYSTEM_OPTION_STRING, SystemOptionString, SystemOptionString);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_ONBOARD_DEVICE, MiscOnboardDeviceVideo, MiscOnboardDevice);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_OEM_STRING,MiscOemString, MiscOemString);
+
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector1, MiscPortInternalConnectorDesignator);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector2, MiscPortInternalConnectorDesignator);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector3, MiscPortInternalConnectorDesignator);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector4, MiscPortInternalConnectorDesignator);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector5, MiscPortInternalConnectorDesignator);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector6, MiscPortInternalConnectorDesignator);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector7, MiscPortInternalConnectorDesignator);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector8, MiscPortInternalConnectorDesignator);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector9, MiscPortInternalConnectorDesignator);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector10, MiscPortInternalConnectorDesignator);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector11, MiscPortInternalConnectorDesignator);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector12, MiscPortInternalConnectorDesignator);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector13, MiscPortInternalConnectorDesignator);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR, MiscPortConnector14, MiscPortInternalConnectorDesignator);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot1, MiscSystemSlotDesignator);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot2, MiscSystemSlotDesignator);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot3, MiscSystemSlotDesignator);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot4, MiscSystemSlotDesignator);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot5, MiscSystemSlotDesignator);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot6, MiscSystemSlotDesignator);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot7, MiscSystemSlotDesignator);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot8, MiscSystemSlotDesignator);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot9, MiscSystemSlotDesignator);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot10, MiscSystemSlotDesignator);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot11, MiscSystemSlotDesignator);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot12, MiscSystemSlotDesignator);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot13, MiscSystemSlotDesignator);
+MISC_SMBIOS_TABLE_EXTERNS(EFI_MISC_SYSTEM_SLOT_DESIGNATION, MiscSystemSlot14, MiscSystemSlotDesignator);
+
+
+//
+// Data Table
+//
+EFI_MISC_SMBIOS_DATA_TABLE mSmbiosMiscDataTable[] = {
+ MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscBiosVendor, MiscBiosVendor),
+ MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscSystemManufacturer, MiscSystemManufacturer),
+ MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscBaseBoardManufacturer, MiscBaseBoardManufacturer),
+ MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscChassisManufacturer, MiscChassisManufacturer),
+ MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscPortConnector1, MiscPortInternalConnectorDesignator),
+ MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscPortConnector2, MiscPortInternalConnectorDesignator),
+ MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscPortConnector3, MiscPortInternalConnectorDesignator),
+ MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscPortConnector4, MiscPortInternalConnectorDesignator),
+ MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscPortConnector5, MiscPortInternalConnectorDesignator),
+ MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscPortConnector6, MiscPortInternalConnectorDesignator),
+ MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscPortConnector7, MiscPortInternalConnectorDesignator),
+ MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscPortConnector8, MiscPortInternalConnectorDesignator),
+ MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscPortConnector9, MiscPortInternalConnectorDesignator),
+ MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscPortConnector10, MiscPortInternalConnectorDesignator),
+ MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscPortConnector11, MiscPortInternalConnectorDesignator),
+ MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscPortConnector12, MiscPortInternalConnectorDesignator),
+ MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscPortConnector13, MiscPortInternalConnectorDesignator),
+ MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscPortConnector14, MiscPortInternalConnectorDesignator),
+ MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscSystemSlot1, MiscSystemSlotDesignator),
+ MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscSystemSlot2, MiscSystemSlotDesignator),
+ MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscSystemSlot3, MiscSystemSlotDesignator),
+ MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscSystemSlot4, MiscSystemSlotDesignator),
+ MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscSystemSlot5, MiscSystemSlotDesignator),
+ MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscSystemSlot6, MiscSystemSlotDesignator),
+ MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscSystemSlot7, MiscSystemSlotDesignator),
+ MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscSystemSlot8, MiscSystemSlotDesignator),
+ MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscSystemSlot9, MiscSystemSlotDesignator),
+ MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscSystemSlot10, MiscSystemSlotDesignator),
+ MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscSystemSlot11, MiscSystemSlotDesignator),
+ MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscSystemSlot12, MiscSystemSlotDesignator),
+ MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscSystemSlot13, MiscSystemSlotDesignator),
+ MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscSystemSlot14, MiscSystemSlotDesignator),
+ MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscOnboardDeviceVideo, MiscOnboardDevice),
+ MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscOemString, MiscOemString),
+ MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(SystemOptionString, SystemOptionString),
+ MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(NumberOfInstallableLanguages, NumberOfInstallableLanguages),
+ MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(MiscBootInfoStatus, MiscBootInfoStatus)
+};
+
+//
+// Number of Data Table entries.
+//
+UINTN mSmbiosMiscDataTableEntries =
+ (sizeof mSmbiosMiscDataTable) / sizeof(EFI_MISC_SMBIOS_DATA_TABLE);
diff --git a/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMiscDxe.inf b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMiscDxe.inf
new file mode 100644
index 0000000000..77904cc13b
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMiscDxe.inf
@@ -0,0 +1,314 @@
+## @file
+# Component description file for Smbios Misc module.
+#
+# This driver parses the mSmbiosMiscDataTable structure
+# and reports any generated data using SMBIOS protocol.
+# SmBios To Misc.Subclass Map Table.
+# SMBIOS Type |SMBIOS Name |Misc Subclass Record |Misc Subclass Name
+# 0 | BIOS Information | 0x2 | BiosVendor
+# 3 | System/Chassis Enclosure | 0x5 | ChassisManufacturer
+# 8 | Port Connector Information | 0x6 | PortInternalConnectorDesignator
+# 9 | System Slot Information | 0x7 | SystemSlotDesignator
+# 10 | On Board Device Information | 0x8 | OnboardDevice
+# 12 | System Configuration Options| 0xA | SystemOptionString
+# 13 | BIOS Language Information | 0xB | NumberOfInstallableLanguages
+# 32 | Boot Information | 0x1A | BootInformationStatus
+# The uni files tagged with "ToolCode="DUMMY"" are included by SmbiosMiscStrings.uni file which is input
+# file for StrGather tool.
+# Copyright (c) 2013-2015 Intel Corporation.
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = SmbiosMisc
+ FILE_GUID = EF0C99B6-B1D3-4025-9405-BF6A560FE0E0
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = SmbiosMiscEntryPoint
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[Sources]
+ MiscOemStringFunction.c
+ MiscOemStringData.c
+ SmbiosMiscEntryPoint.c
+ SmbiosMiscDataTable.c
+ MiscSystemManufacturerData.c
+ MiscSystemManufacturerFunction.c
+ MiscBaseBoardManufacturerData.c
+ MiscBaseBoardManufacturerFunction.c
+ MiscOnboardDeviceFunction.c
+ MiscOnboardDeviceData.c
+ MiscSystemSlotDesignationFunction.c
+ MiscSystemSlotDesignationData.c
+ MiscNumberOfInstallableLanguagesFunction.c
+ MiscNumberOfInstallableLanguagesData.c
+ MiscChassisManufacturerFunction.c
+ MiscChassisManufacturerData.c
+ MiscBootInformationFunction.c
+ MiscBootInformationData.c
+ MiscBiosVendorFunction.c
+ MiscBiosVendorData.c
+ MiscSystemOptionStringFunction.c
+ MiscSystemOptionStringData.c
+ MiscPortInternalConnectorDesignatorFunction.c
+ MiscPortInternalConnectorDesignatorData.c
+ SmbiosMisc.h
+ MiscDevicePath.h
+ SmbiosMiscStrings.uni
+ CommonHeader.h
+
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ IntelFrameworkPkg/IntelFrameworkPkg.dec
+ QuarkPlatformPkg/QuarkPlatformPkg.dec
+
+[LibraryClasses]
+ PcdLib
+ HiiLib
+ MemoryAllocationLib
+ DevicePathLib
+ BaseMemoryLib
+ BaseLib
+ DebugLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+ UefiLib
+
+[Protocols]
+ gEfiSmbiosProtocolGuid # PROTOCOL ALWAYS_CONSUMED
+
+[Pcd]
+ gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultPlatformLang
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareRevision
+ gQuarkPlatformTokenSpaceGuid.PcdPlatformTypeName
+ gQuarkPlatformTokenSpaceGuid.PcdFlashAreaSize
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSBiosVendor
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSBiosReleaseDate
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSBiosStartAddress
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSBiosChar
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSBiosCharEx1
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSBiosCharEx2
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemManufacturer
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemProductName
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemVersion
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSerialNumber
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemUuid
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSKUNumber
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemFamily
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSBoardManufacturer
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSBoardProductName
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSBoardVersion
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSBoardSerialNumber
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSChassisManufacturer
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSChassisVersion
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSChassisSerialNumber
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSChassisAssetTag
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSChassisType
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSChassisBootupState
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSChassisPowerSupplyState
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSChassisSecurityState
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSChassisOemDefined
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSChassisHeight
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSChassisNumberPowerCords
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSChassisElementCount
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSChassisElementRecordLength
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSConnectorNumber
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort1InternalConnectorDesignator
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort1ExternalConnectorDesignator
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort1InternalConnectorType
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort1ExternalConnectorType
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort1Type
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort2InternalConnectorDesignator
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort2ExternalConnectorDesignator
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort2InternalConnectorType
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort2ExternalConnectorType
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort2Type
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort3InternalConnectorDesignator
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort3ExternalConnectorDesignator
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort3InternalConnectorType
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort3ExternalConnectorType
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort3Type
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort4InternalConnectorDesignator
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort4ExternalConnectorDesignator
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort4InternalConnectorType
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort4ExternalConnectorType
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort4Type
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort5InternalConnectorDesignator
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort5ExternalConnectorDesignator
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort5InternalConnectorType
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort5ExternalConnectorType
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort5Type
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort6InternalConnectorDesignator
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort6ExternalConnectorDesignator
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort6InternalConnectorType
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort6ExternalConnectorType
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort6Type
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort7InternalConnectorDesignator
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort7ExternalConnectorDesignator
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort7InternalConnectorType
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort7ExternalConnectorType
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort7Type
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort8InternalConnectorDesignator
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort8ExternalConnectorDesignator
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort8InternalConnectorType
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort8ExternalConnectorType
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort8Type
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort9InternalConnectorDesignator
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort9ExternalConnectorDesignator
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort9InternalConnectorType
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort9ExternalConnectorType
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort9Type
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort10InternalConnectorDesignator
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort10ExternalConnectorDesignator
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort10InternalConnectorType
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort10ExternalConnectorType
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort10Type
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort11InternalConnectorDesignator
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort11ExternalConnectorDesignator
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort11InternalConnectorType
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort11ExternalConnectorType
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort11Type
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort12InternalConnectorDesignator
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort12ExternalConnectorDesignator
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort12InternalConnectorType
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort12ExternalConnectorType
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort12Type
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort13InternalConnectorDesignator
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort13ExternalConnectorDesignator
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort13InternalConnectorType
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort13ExternalConnectorType
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort13Type
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort14InternalConnectorDesignator
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort14ExternalConnectorDesignator
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort14InternalConnectorType
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort14ExternalConnectorType
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort14Type
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort15InternalConnectorDesignator
+
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort15InternalConnectorType
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort15ExternalConnectorType
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort15Type
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort16InternalConnectorDesignator
+
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort16InternalConnectorType
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort16ExternalConnectorType
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSPort16Type
+
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlotNumber
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot1Designation
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot1Type
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot1DataBusWidth
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot1Usage
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot1Length
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot1Id
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot1Characteristics
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot2Designation
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot2Type
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot2DataBusWidth
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot2Usage
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot2Length
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot2Id
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot2Characteristics
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot3Designation
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot3Type
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot3DataBusWidth
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot3Usage
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot3Length
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot3Id
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot3Characteristics
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot4Designation
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot4Type
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot4DataBusWidth
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot4Usage
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot4Length
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot4Id
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot4Characteristics
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot5Designation
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot5Type
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot5DataBusWidth
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot5Usage
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot5Length
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot5Id
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot5Characteristics
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot6Designation
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot6Type
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot6DataBusWidth
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot6Usage
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot6Length
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot6Id
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot6Characteristics
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot7Designation
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot7Type
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot7DataBusWidth
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot7Usage
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot7Length
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot7Id
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot7Characteristics
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot8Designation
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot8Type
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot8DataBusWidth
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot8Usage
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot8Length
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot8Id
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot8Characteristics
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot9Designation
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot9Type
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot9DataBusWidth
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot9Usage
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot9Length
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot9Id
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot9Characteristics
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot10Designation
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot10Type
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot10DataBusWidth
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot10Usage
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot10Length
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot10Id
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot10Characteristics
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot11Designation
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot11Type
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot11DataBusWidth
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot11Usage
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot11Length
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot11Id
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot11Characteristics
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot12Designation
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot12Type
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot12DataBusWidth
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot12Usage
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot12Length
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot12Id
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot12Characteristics
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot13Designation
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot13Type
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot13DataBusWidth
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot13Usage
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot13Length
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot13Id
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot13Characteristics
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot14Designation
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot14Type
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot14DataBusWidth
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot14Usage
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot14Length
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot14Id
+ gQuarkPlatformTokenSpaceGuid.PcdSMBIOSSystemSlot14Characteristics
+
+[Depex]
+ gEfiSmbiosProtocolGuid
diff --git a/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMiscEntryPoint.c b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMiscEntryPoint.c
new file mode 100644
index 0000000000..afb5a3e5ae
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMiscEntryPoint.c
@@ -0,0 +1,88 @@
+/** @file
+This driver parses the mSmbiosMiscDataTable structure and reports
+any generated data using SMBIOS protocol.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+
+**/
+
+
+#include "CommonHeader.h"
+
+#include "SmbiosMisc.h"
+
+
+extern UINT8 SmbiosMiscStrings[];
+EFI_HANDLE mImageHandle;
+
+EFI_HII_HANDLE mHiiHandle;
+
+
+
+/**
+ Standard EFI driver point. This driver parses the mSmbiosMiscDataTable
+ structure and reports any generated data using SMBIOS protocol.
+
+ @param ImageHandle Handle for the image of this driver
+ @param SystemTable Pointer to the EFI System Table
+
+ @retval EFI_SUCCESS The data was successfully stored.
+
+**/
+EFI_STATUS
+EFIAPI
+SmbiosMiscEntryPoint(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ UINTN Index;
+ EFI_STATUS EfiStatus;
+ EFI_SMBIOS_PROTOCOL *Smbios;
+
+
+ mImageHandle = ImageHandle;
+
+ EfiStatus = gBS->LocateProtocol(&gEfiSmbiosProtocolGuid, NULL, (VOID**)&Smbios);
+
+ if (EFI_ERROR(EfiStatus)) {
+ DEBUG((EFI_D_ERROR, "Could not locate SMBIOS protocol. %r\n", EfiStatus));
+ return EfiStatus;
+ }
+
+ mHiiHandle = HiiAddPackages (
+ &gEfiCallerIdGuid,
+ mImageHandle,
+ SmbiosMiscStrings,
+ NULL
+ );
+ ASSERT (mHiiHandle != NULL);
+
+ for (Index = 0; Index < mSmbiosMiscDataTableEntries; ++Index) {
+ //
+ // If the entry have a function pointer, just log the data.
+ //
+ if (mSmbiosMiscDataTable[Index].Function != NULL) {
+ EfiStatus = (*mSmbiosMiscDataTable[Index].Function)(
+ mSmbiosMiscDataTable[Index].RecordData,
+ Smbios
+ );
+
+ if (EFI_ERROR(EfiStatus)) {
+ DEBUG((EFI_D_ERROR, "Misc smbios store error. Index=%d, ReturnStatus=%r\n", Index, EfiStatus));
+ return EfiStatus;
+ }
+ }
+ }
+
+ return EfiStatus;
+}
diff --git a/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMiscStrings.uni b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMiscStrings.uni
new file mode 100644
index 0000000000..7c21cf43cb
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Dxe/SmbiosMiscDxe/SmbiosMiscStrings.uni
@@ -0,0 +1,32 @@
+// /** @file
+// SmbiosMisc formset.
+//
+// Copyright (c) 2013-2015 Intel Corporation.
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+//
+// **/
+
+/=#
+
+#langdef en-US "English"
+
+#string STR_MISC_SUBCLASS_DRIVER_TITLE #language en-US "SMBIOS Misc subclass driver"
+
+
+#include "MiscBiosVendor.uni"
+#include "MiscChassisManufacturer.uni"
+#include "MiscPortInternalConnectorDesignator.uni"
+#include "MiscSystemManufacturer.uni"
+#include "MiscBaseBoardManufacturer.uni"
+#include "MiscSystemOptionString.uni"
+#include "MiscSystemSlotDesignation.uni"
+#include "MiscOnboardDevice.uni"
+#include "MiscOemString.uni"
diff --git a/QuarkPlatformPkg/Platform/Pei/PlatformConfig/PlatformConfigPei.c b/QuarkPlatformPkg/Platform/Pei/PlatformConfig/PlatformConfigPei.c
new file mode 100644
index 0000000000..d61dce7b32
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Pei/PlatformConfig/PlatformConfigPei.c
@@ -0,0 +1,87 @@
+/** @file
+Principle source module for Clanton Peak platform config PEIM driver.
+
+Copyright (c) 2013 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <PiPei.h>
+#include <Library/IntelQNCLib.h>
+#include <Library/PlatformHelperLib.h>
+#include <Library/QNCAccessLib.h>
+
+VOID
+EFIAPI
+LegacySpiProtect (
+ VOID
+ )
+{
+ UINT32 RegVal;
+
+ RegVal = PcdGet32 (PcdLegacyProtectedBIOSRange0Pei);
+ if (RegVal != 0) {
+ PlatformWriteFirstFreeSpiProtect (
+ RegVal,
+ 0,
+ 0
+ );
+ }
+ RegVal = PcdGet32 (PcdLegacyProtectedBIOSRange1Pei);
+ if (RegVal != 0) {
+ PlatformWriteFirstFreeSpiProtect (
+ RegVal,
+ 0,
+ 0
+ );
+ }
+ RegVal = PcdGet32 (PcdLegacyProtectedBIOSRange2Pei);
+ if (RegVal != 0) {
+ PlatformWriteFirstFreeSpiProtect (
+ RegVal,
+ 0,
+ 0
+ );
+ }
+
+ //
+ // Make legacy SPI READ/WRITE enabled if not a secure build
+ //
+ LpcPciCfg32And (R_QNC_LPC_BIOS_CNTL, ~B_QNC_LPC_BIOS_CNTL_BIOSWE);
+}
+
+/** PlatformConfigPei driver entry point.
+
+ Platform config in PEI stage.
+
+ @param[in] FfsHeader Pointer to Firmware File System file header.
+ @param[in] PeiServices General purpose services available to every PEIM.
+
+ @retval EFI_SUCCESS Platform config success.
+*/
+EFI_STATUS
+EFIAPI
+PlatformConfigPeiInit (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ //
+ // Do SOC Init Pre memory init.
+ //
+ PeiQNCPreMemInit ();
+
+ //
+ // Protect areas specified by PCDs.
+ //
+ LegacySpiProtect ();
+
+ return EFI_SUCCESS;
+}
diff --git a/QuarkPlatformPkg/Platform/Pei/PlatformConfig/PlatformConfigPei.inf b/QuarkPlatformPkg/Platform/Pei/PlatformConfig/PlatformConfigPei.inf
new file mode 100644
index 0000000000..330e0a4547
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Pei/PlatformConfig/PlatformConfigPei.inf
@@ -0,0 +1,51 @@
+## @file
+# Component description file for Clanton Peak platform config PEIM module.
+#
+# Copyright (c) 2013 Intel Corporation.
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = PlatformConfigPei
+ FILE_GUID = 55961E20-B0D9-4553-9948-E3ECF0BE0889
+ MODULE_TYPE = PEIM
+ VERSION_STRING = 1.0
+ ENTRY_POINT = PlatformConfigPeiInit
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32
+#
+
+[Sources]
+ PlatformConfigPei.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ QuarkPlatformPkg/QuarkPlatformPkg.dec
+ QuarkSocPkg/QuarkSocPkg.dec
+
+[LibraryClasses]
+ PeimEntryPoint
+ PcdLib
+ IntelQNCLib
+ PlatformHelperLib
+ QNCAccessLib
+
+[Pcd]
+ gQuarkPlatformTokenSpaceGuid.PcdLegacyProtectedBIOSRange0Pei
+ gQuarkPlatformTokenSpaceGuid.PcdLegacyProtectedBIOSRange1Pei
+ gQuarkPlatformTokenSpaceGuid.PcdLegacyProtectedBIOSRange2Pei
+
+[Depex]
+ TRUE
diff --git a/QuarkPlatformPkg/Platform/Pei/PlatformInit/BootMode.c b/QuarkPlatformPkg/Platform/Pei/PlatformInit/BootMode.c
new file mode 100644
index 0000000000..0dd3d24cf3
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Pei/PlatformInit/BootMode.c
@@ -0,0 +1,257 @@
+/** @file
+This file provide the function to detect boot mode
+
+Copyright (c) 2013 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+
+#include "CommonHeader.h"
+#include <Pi/PiFirmwareVolume.h>
+
+EFI_PEI_PPI_DESCRIPTOR mPpiListRecoveryBootMode = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiPeiBootInRecoveryModePpiGuid,
+ NULL
+};
+
+/**
+ If the box was opened, it's boot with full config.
+ If the box is closed, then
+ 1. If it's first time to boot, it's boot with full config .
+ 2. If the ChassisIntrution is selected, force to be a boot with full config
+ 3. Otherwise it's boot with no change.
+
+ @param PeiServices General purpose services available to every PEIM.
+
+ @retval TRUE If it's boot with no change.
+
+ @retval FALSE If boot with no change.
+**/
+BOOLEAN
+IsBootWithNoChange (
+ IN EFI_PEI_SERVICES **PeiServices
+ )
+{
+ BOOLEAN IsFirstBoot = FALSE;
+
+ BOOLEAN EnableFastBoot = FALSE;
+ IsFirstBoot = PcdGetBool(PcdBootState);
+ EnableFastBoot = PcdGetBool (PcdEnableFastBoot);
+
+ DEBUG ((EFI_D_INFO, "IsFirstBoot = %x , EnableFastBoot= %x. \n", IsFirstBoot, EnableFastBoot));
+
+ if ((!IsFirstBoot) && EnableFastBoot) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+
+/**
+
+Routine Description:
+
+ This function is used to verify if the FV header is validate.
+
+ @param FwVolHeader - The FV header that to be verified.
+
+ @retval EFI_SUCCESS - The Fv header is valid.
+ @retval EFI_NOT_FOUND - The Fv header is invalid.
+
+**/
+EFI_STATUS
+ValidateFvHeader (
+ EFI_BOOT_MODE *BootMode
+ )
+{
+ UINT16 *Ptr;
+ UINT16 HeaderLength;
+ UINT16 Checksum;
+
+ EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
+
+ if (BOOT_IN_RECOVERY_MODE == *BootMode) {
+ DEBUG ((EFI_D_INFO, "Boot mode recovery\n"));
+ return EFI_SUCCESS;
+ }
+ //
+ // Let's check whether FvMain header is valid, if not enter into recovery mode
+ //
+ //
+ // Verify the header revision, header signature, length
+ // Length of FvBlock cannot be 2**64-1
+ // HeaderLength cannot be an odd number
+ //
+ FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)PcdGet32(PcdFlashFvMainBase);
+ if ((FwVolHeader->Revision != EFI_FVH_REVISION)||
+ (FwVolHeader->Signature != EFI_FVH_SIGNATURE) ||
+ (FwVolHeader->FvLength == ((UINT64) -1)) ||
+ ((FwVolHeader->HeaderLength & 0x01) != 0)
+ ) {
+ return EFI_NOT_FOUND;
+ }
+ //
+ // Verify the header checksum
+ //
+ HeaderLength = (UINT16) (FwVolHeader->HeaderLength / 2);
+ Ptr = (UINT16 *) FwVolHeader;
+ Checksum = 0;
+ while (HeaderLength > 0) {
+ Checksum = Checksum +*Ptr;
+ Ptr++;
+ HeaderLength--;
+ }
+
+ if (Checksum != 0) {
+ return EFI_NOT_FOUND;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+
+ Check whether go to recovery path
+ @retval TRUE Go to recovery path
+ @retval FALSE Go to normal path
+
+**/
+BOOLEAN
+OemRecoveryBootMode ()
+{
+ return PlatformIsBootWithRecoveryStage1 ();
+}
+
+/**
+ Peform the boot mode determination logic
+ If the box is closed, then
+ 1. If it's first time to boot, it's boot with full config .
+ 2. If the ChassisIntrution is selected, force to be a boot with full config
+ 3. Otherwise it's boot with no change.
+
+ @param PeiServices General purpose services available to every PEIM.
+
+ @param BootMode The detected boot mode.
+
+ @retval EFI_SUCCESS if the boot mode could be set
+**/
+EFI_STATUS
+UpdateBootMode (
+ IN EFI_PEI_SERVICES **PeiServices,
+ OUT EFI_BOOT_MODE *BootMode
+ )
+{
+ EFI_STATUS Status;
+ EFI_BOOT_MODE NewBootMode;
+ PEI_CAPSULE_PPI *Capsule;
+ CHAR8 UserSelection;
+ UINT32 Straps32;
+
+ //
+ // Read Straps. Used later if recovery boot.
+ //
+ Straps32 = QNCAltPortRead (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_STPDDRCFG);
+
+ //
+ // Check if we need to boot in recovery mode
+ //
+ if ((ValidateFvHeader (BootMode) != EFI_SUCCESS)) {
+ DEBUG ((EFI_D_INFO, "Force Boot mode recovery\n"));
+ NewBootMode = BOOT_IN_RECOVERY_MODE;
+ Status = PeiServicesInstallPpi (&mPpiListRecoveryBootMode);
+ ASSERT_EFI_ERROR (Status);
+ if (OemRecoveryBootMode () == FALSE) {
+ DEBUG ((EFI_D_INFO, "Recovery stage1 not Active, reboot to activate recovery stage1 image\n"));
+ OemInitiateRecoveryAndWait ();
+ }
+ } else if (OemRecoveryBootMode ()) {
+ DEBUG ((EFI_D_INFO, "Boot mode recovery\n"));
+ NewBootMode = BOOT_IN_RECOVERY_MODE;
+ Status = PeiServicesInstallPpi (&mPpiListRecoveryBootMode);
+ ASSERT_EFI_ERROR (Status);
+ } else if (QNCCheckS3AndClearState ()) {
+ //
+ // Determine if we're in capsule update mode
+ //
+ Status = PeiServicesLocatePpi (
+ &gPeiCapsulePpiGuid,
+ 0,
+ NULL,
+ (VOID **)&Capsule
+ );
+ if (Status == EFI_SUCCESS) {
+ Status = Capsule->CheckCapsuleUpdate (PeiServices);
+ if (Status == EFI_SUCCESS) {
+ DEBUG ((EFI_D_INFO, "Boot mode Flash Update\n"));
+ NewBootMode = BOOT_ON_FLASH_UPDATE;
+ } else {
+ DEBUG ((EFI_D_INFO, "Boot mode S3 resume\n"));
+ NewBootMode = BOOT_ON_S3_RESUME;
+ }
+ } else {
+ DEBUG ((EFI_D_INFO, "Boot mode S3 resume\n"));
+ NewBootMode = BOOT_ON_S3_RESUME;
+ }
+ } else {
+ //
+ // Check if this is a power on reset
+ //
+ if (QNCCheckPowerOnResetAndClearState ()) {
+ DEBUG ((EFI_D_INFO, "Power On Reset\n"));
+ }
+ if (IsBootWithNoChange (PeiServices)) {
+ DEBUG ((EFI_D_INFO, "Boot with Minimum cfg\n"));
+ NewBootMode = BOOT_ASSUMING_NO_CONFIGURATION_CHANGES;
+ } else {
+ DEBUG ((EFI_D_INFO, "Boot with Full cfg\n"));
+ NewBootMode = BOOT_WITH_FULL_CONFIGURATION;
+ }
+ }
+ *BootMode = NewBootMode;
+ Status = PeiServicesSetBootMode (NewBootMode);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // If Recovery Boot then prompt the user to insert a USB key with recovery nodule and
+ // continue with the recovery. Also give the user a chance to retry a normal boot.
+ //
+ if (NewBootMode == BOOT_IN_RECOVERY_MODE) {
+ if ((Straps32 & B_STPDDRCFG_FORCE_RECOVERY) == 0) {
+ DEBUG ((EFI_D_ERROR, "*****************************************************************\n"));
+ DEBUG ((EFI_D_ERROR, "***** Force Recovery Jumper Detected. *****\n"));
+ DEBUG ((EFI_D_ERROR, "***** Attempting auto recovery of system flash. *****\n"));
+ DEBUG ((EFI_D_ERROR, "***** Expecting USB key with recovery module connected. *****\n"));
+ DEBUG ((EFI_D_ERROR, "***** PLEASE REMOVE FORCE RECOVERY JUMPER. *****\n"));
+ DEBUG ((EFI_D_ERROR, "*****************************************************************\n"));
+ } else {
+ DEBUG ((EFI_D_ERROR, "*****************************************************************\n"));
+ DEBUG ((EFI_D_ERROR, "***** ERROR: System boot failure!!!!!!! *****\n"));
+ DEBUG ((EFI_D_ERROR, "***** - Press 'R' if you wish to force system recovery *****\n"));
+ DEBUG ((EFI_D_ERROR, "***** (connect USB key with recovery module first) *****\n"));
+ DEBUG ((EFI_D_ERROR, "***** - Press any other key to attempt another boot *****\n"));
+ DEBUG ((EFI_D_ERROR, "*****************************************************************\n"));
+
+ UserSelection = PlatformDebugPortGetChar8 ();
+ if ((UserSelection != 'R') && (UserSelection != 'r')) {
+ DEBUG ((EFI_D_ERROR, "New boot attempt selected........\n"));
+ //
+ // Initialte the cold reset
+ //
+ ResetCold ();
+ }
+ DEBUG ((EFI_D_ERROR, "Recovery boot selected..........\n"));
+ }
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/QuarkPlatformPkg/Platform/Pei/PlatformInit/CommonHeader.h b/QuarkPlatformPkg/Platform/Pei/PlatformInit/CommonHeader.h
new file mode 100644
index 0000000000..3630f347b6
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Pei/PlatformInit/CommonHeader.h
@@ -0,0 +1,84 @@
+/** @file
+Common header file shared by all source files.
+
+This file includes package header files, library classes and protocol, PPI & GUID definitions.
+
+Copyright (c) 2013 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+
+#ifndef __COMMON_HEADER_H_
+#define __COMMON_HEADER_H_
+
+
+
+#include <PiPei.h>
+#include <IntelQNCPeim.h>
+#include "Ioh.h"
+#include <Platform.h>
+#include <PlatformBoards.h>
+
+#include <IndustryStandard/SmBus.h>
+#include <IndustryStandard/Pci22.h>
+
+#include <Guid/AcpiS3Context.h>
+#include <Ppi/AtaController.h>
+#include <Guid/Capsule.h>
+#include <Ppi/MasterBootMode.h>
+#include <Guid/MemoryTypeInformation.h>
+#include <Guid/RecoveryDevice.h>
+#include <Guid/MemoryConfigData.h>
+#include <Guid/MemoryOverwriteControl.h>
+#include <Guid/CapsuleVendor.h>
+#include <Guid/QuarkCapsuleGuid.h>
+#include <Ppi/ReadOnlyVariable2.h>
+#include <Ppi/FvLoadFile.h>
+#include <Guid/SmramMemoryReserve.h>
+#include <Ppi/DeviceRecoveryModule.h>
+#include <Ppi/Capsule.h>
+#include <Ppi/Reset.h>
+#include <Ppi/Stall.h>
+#include <Ppi/BootInRecoveryMode.h>
+#include <Guid/FirmwareFileSystem2.h>
+#include <Ppi/MemoryDiscovered.h>
+#include <Ppi/RecoveryModule.h>
+#include <Ppi/Smbus2.h>
+#include <Ppi/FirmwareVolumeInfo.h>
+#include <Ppi/EndOfPeiPhase.h>
+
+#include <Library/DebugLib.h>
+#include <Library/PeimEntryPoint.h>
+#include <Library/BaseLib.h>
+#include <Library/PeiServicesTablePointerLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/HobLib.h>
+#include <Library/PciCf8Lib.h>
+#include <Library/IoLib.h>
+#include <Library/PciLib.h>
+#include <Library/ReportStatusCodeLib.h>
+#include <Library/IntelQNCLib.h>
+#include <Library/PcdLib.h>
+#include <Library/SmbusLib.h>
+#include <Library/RecoveryOemHookLib.h>
+#include <Library/TimerLib.h>
+#include <Library/PrintLib.h>
+#include <Library/ResetSystemLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PerformanceLib.h>
+#include <Library/CacheMaintenanceLib.h>
+#include <Library/MtrrLib.h>
+#include <Library/QNCAccessLib.h>
+#include <Library/PlatformHelperLib.h>
+#include <Library/PlatformPcieHelperLib.h>
+
+#include <Register/Cpuid.h>
+
+#endif
diff --git a/QuarkPlatformPkg/Platform/Pei/PlatformInit/Generic/Recovery.c b/QuarkPlatformPkg/Platform/Pei/PlatformInit/Generic/Recovery.c
new file mode 100644
index 0000000000..ea67ba9d63
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Pei/PlatformInit/Generic/Recovery.c
@@ -0,0 +1,501 @@
+/** @file
+Install Platform EFI_PEI_RECOVERY_MODULE_PPI and Implementation of
+EFI_PEI_LOAD_RECOVERY_CAPSULE service.
+
+Copyright (c) 2013 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "CommonHeader.h"
+#include "PlatformEarlyInit.h"
+
+#include <Ppi/BlockIo.h>
+
+//
+// Capsule Types supported in this platform module
+//
+#include <Guid/CapsuleOnFatFloppyDisk.h>
+#include <Guid/CapsuleOnFatIdeDisk.h>
+#include <Guid/CapsuleOnFatUsbDisk.h>
+#include <Guid/CapsuleOnDataCD.h>
+#include <Guid/QuarkCapsuleGuid.h>
+
+#include <Ppi/RecoveryModule.h>
+#include <Ppi/DeviceRecoveryModule.h>
+
+#include <Library/PeiServicesLib.h>
+
+//
+// Required Service
+//
+EFI_STATUS
+EFIAPI
+PlatformRecoveryModule (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_RECOVERY_MODULE_PPI *This
+ );
+
+VOID
+AssertNoCapsulesError (
+ IN EFI_PEI_SERVICES **PeiServices
+ );
+
+VOID
+AssertMediaDeviceError (
+ IN EFI_PEI_SERVICES **PeiServices
+ );
+
+VOID
+ReportLoadCapsuleSuccess (
+ IN EFI_PEI_SERVICES **PeiServices
+ );
+
+VOID
+CheckIfMediaPresentOnBlockIoDevice (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN OUT BOOLEAN *MediaDeviceError,
+ IN OUT BOOLEAN *MediaPresent
+ );
+
+//
+// Module globals
+//
+EFI_PEI_RECOVERY_MODULE_PPI mRecoveryPpi = { PlatformRecoveryModule };
+
+EFI_PEI_PPI_DESCRIPTOR mRecoveryPpiList = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiPeiRecoveryModulePpiGuid,
+ &mRecoveryPpi
+};
+
+EFI_STATUS
+EFIAPI
+PeimInitializeRecovery (
+ IN EFI_PEI_SERVICES **PeiServices
+ )
+/*++
+
+Routine Description:
+
+ Provide the functionality of the Recovery Module.
+
+Arguments:
+
+ PeiServices - General purpose services available to every PEIM.
+
+Returns:
+
+ EFI_SUCCESS - If the interface could be successfully
+ installed.
+
+--*/
+{
+ EFI_STATUS Status;
+
+ Status = PeiServicesInstallPpi (&mRecoveryPpiList);
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+PlatformRecoveryModule (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_RECOVERY_MODULE_PPI *This
+ )
+/*++
+
+Routine Description:
+
+ Provide the functionality of the Platform Recovery Module.
+
+Arguments:
+
+ PeiServices - General purpose services available to every PEIM.
+ This - Pointer to EFI_PEI_RECOVERY_MODULE_PPI.
+
+Returns:
+
+ EFI_SUCCESS - If the interface could be successfully
+ installed.
+ EFI_UNSUPPORTED - Not supported.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_PEI_DEVICE_RECOVERY_MODULE_PPI *DeviceRecoveryModule;
+ UINTN NumberOfImageProviders;
+ BOOLEAN ProviderAvailable;
+ UINTN NumberRecoveryCapsules;
+ UINTN RecoveryCapsuleSize;
+ EFI_GUID DeviceId;
+ BOOLEAN ImageFound;
+ EFI_PHYSICAL_ADDRESS Address;
+ VOID *Buffer;
+ EFI_CAPSULE_HEADER *CapsuleHeader;
+ EFI_PEI_HOB_POINTERS Hob;
+ EFI_PEI_HOB_POINTERS HobOld;
+ BOOLEAN HobUpdate;
+ EFI_FIRMWARE_VOLUME_HEADER *FvHeader;
+ UINTN Index;
+ EFI_STATUS AuthStatus;
+ EFI_GUID mEfiCapsuleHeaderGuid = QUARK_CAPSULE_GUID;
+
+ Index = 0;
+
+ Status = EFI_SUCCESS;
+ AuthStatus = EFI_SUCCESS;
+ HobUpdate = FALSE;
+
+ ProviderAvailable = TRUE;
+ ImageFound = FALSE;
+ NumberOfImageProviders = 0;
+
+ DeviceRecoveryModule = NULL;
+
+ DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Recovery Entry\n"));
+
+ //
+ // Search the platform for some recovery capsule if the DXE IPL
+ // discovered a recovery condition and has requested a load.
+ //
+ while (ProviderAvailable) {
+
+ Status = PeiServicesLocatePpi (
+ &gEfiPeiDeviceRecoveryModulePpiGuid,
+ Index,
+ NULL,
+ (VOID **)&DeviceRecoveryModule
+ );
+
+ if (!EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Device Recovery PPI located\n"));
+ NumberOfImageProviders++;
+
+ Status = DeviceRecoveryModule->GetNumberRecoveryCapsules (
+ PeiServices,
+ DeviceRecoveryModule,
+ &NumberRecoveryCapsules
+ );
+
+ DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Number Of Recovery Capsules: %d\n", NumberRecoveryCapsules));
+
+ if (NumberRecoveryCapsules == 0) {
+ Index++;
+ } else {
+ break;
+ }
+ } else {
+ ProviderAvailable = FALSE;
+ }
+ }
+ //
+ // The number of recovery capsules is 0.
+ //
+ if (!ProviderAvailable) {
+ AssertNoCapsulesError (PeiServices);
+ }
+ //
+ // If there is an image provider, get the capsule ID
+ //
+ if (ProviderAvailable) {
+ RecoveryCapsuleSize = 0;
+ if (FeaturePcdGet (PcdFrameworkCompatibilitySupport)) {
+ Status = DeviceRecoveryModule->GetRecoveryCapsuleInfo (
+ PeiServices,
+ DeviceRecoveryModule,
+ 0,
+ &RecoveryCapsuleSize,
+ &DeviceId
+ );
+ } else {
+ Status = DeviceRecoveryModule->GetRecoveryCapsuleInfo (
+ PeiServices,
+ DeviceRecoveryModule,
+ 1,
+ &RecoveryCapsuleSize,
+ &DeviceId
+ );
+
+
+ }
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Recovery Capsule Size: %d\n", RecoveryCapsuleSize));
+
+ //
+ // Only support the 2 capsule types known
+ // Future enhancement is to rank-order the selection
+ //
+ if ((!CompareGuid (&DeviceId, &gPeiCapsuleOnFatIdeDiskGuid)) &&
+ (!CompareGuid (&DeviceId, &gPeiCapsuleOnDataCDGuid)) &&
+ (!CompareGuid (&DeviceId, &gPeiCapsuleOnFatUsbDiskGuid))
+ ) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Buffer = NULL;
+ Address = (UINTN) AllocatePages ((RecoveryCapsuleSize - 1) / 0x1000 + 1);
+ ASSERT (Address);
+
+ Buffer = (UINT8 *) (UINTN) Address;
+ if (FeaturePcdGet (PcdFrameworkCompatibilitySupport)) {
+ Status = DeviceRecoveryModule->LoadRecoveryCapsule (
+ PeiServices,
+ DeviceRecoveryModule,
+ 0,
+ Buffer
+ );
+ } else {
+ Status = DeviceRecoveryModule->LoadRecoveryCapsule (
+ PeiServices,
+ DeviceRecoveryModule,
+ 1,
+ Buffer
+ );
+
+ }
+
+ DEBUG ((EFI_D_INFO | EFI_D_LOAD, "LoadRecoveryCapsule Returns: %r\n", Status));
+
+ if (Status == EFI_DEVICE_ERROR) {
+ AssertMediaDeviceError (PeiServices);
+ }
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ } else {
+ ReportLoadCapsuleSuccess (PeiServices);
+ }
+
+ //
+ // Update FV Hob if found
+ //
+ Buffer = (VOID *)((UINT8 *) Buffer);
+ Status = PeiServicesGetHobList ((VOID **)&Hob.Raw);
+ 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));
+
+ if (Hob.FirmwareVolume->BaseAddress == (UINTN) PcdGet32 (PcdFlashFvMainBase)) {
+ HobUpdate = TRUE;
+ //
+ // This looks like the Hob we are interested in
+ //
+ DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Hob Updated\n"));
+ Hob.FirmwareVolume->BaseAddress = (UINTN) Buffer;
+ Hob.FirmwareVolume->Length = RecoveryCapsuleSize;
+ }
+ }
+
+ Hob.Raw = GET_NEXT_HOB (Hob);
+ }
+ //
+ // Check if the top of the file is a firmware volume header
+ //
+ FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) Buffer;
+ CapsuleHeader = (EFI_CAPSULE_HEADER *) Buffer;
+ if (FvHeader->Signature == EFI_FVH_SIGNATURE) {
+ //
+ // build FV Hob if it is not built before
+ //
+ if (!HobUpdate) {
+ DEBUG ((EFI_D_INFO | EFI_D_LOAD, "FV Hob is not found, Build FV Hob then..\n"));
+ BuildFvHob (
+ (UINTN) Buffer,
+ FvHeader->FvLength
+ );
+
+ DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Install FV Info PPI..\n"));
+
+ PeiServicesInstallFvInfoPpi (
+ NULL,
+ Buffer,
+ (UINT32) FvHeader->FvLength,
+ NULL,
+ NULL
+ );
+ }
+ //
+ // Point to the location immediately after the FV.
+ //
+ CapsuleHeader = (EFI_CAPSULE_HEADER *) ((UINT8 *) Buffer + FvHeader->FvLength);
+ }
+
+ //
+ // Check if pointer is still within the buffer
+ //
+ if ((UINTN) CapsuleHeader < (UINTN) ((UINT8 *) Buffer + RecoveryCapsuleSize)) {
+
+ //
+ // Check if it is a capsule
+ //
+ if (CompareGuid ((EFI_GUID *) CapsuleHeader, &mEfiCapsuleHeaderGuid)) {
+
+ //
+ // Set bootmode to capsule update so the capsule hob gets the right bootmode in the hob header.
+ //
+ Status = PeiServicesSetBootMode (BOOT_ON_FLASH_UPDATE);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Build capsule hob
+ //
+ BuildCvHob ((EFI_PHYSICAL_ADDRESS)(UINTN)CapsuleHeader, (UINT64)CapsuleHeader->CapsuleImageSize);
+ }
+ }
+ }
+
+ DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Recovery Module Returning: %r\n", Status));
+ return Status;
+}
+
+/*
+ AssertNoCapsulesError:
+ There were no recovery capsules found.
+ Case 1: Report the error that no recovery block io device/media is readable and assert.
+ Case 2: Report the error that there is no media present on any recovery block io device and assert.
+ Case 3: There is media present on some recovery block io device,
+ but there is no recovery capsule on it. Report the error and assert.
+*/
+VOID
+AssertNoCapsulesError (
+ IN EFI_PEI_SERVICES **PeiServices
+ )
+{
+ BOOLEAN MediaDeviceError;
+ BOOLEAN MediaPresent;
+
+ MediaDeviceError = TRUE;
+ MediaPresent = FALSE;
+
+ CheckIfMediaPresentOnBlockIoDevice (PeiServices, &MediaDeviceError, &MediaPresent);
+/* if (MediaDeviceError) {
+ ReportStatusCode (
+ (EFI_ERROR_CODE | EFI_ERROR_UNRECOVERED),
+ (EFI_PERIPHERAL_RECOVERY_MEDIA | EFI_P_EC_MEDIA_DEVICE_ERROR)
+ );
+
+ } else if (!MediaPresent) {
+ ReportStatusCode (
+ (EFI_ERROR_CODE | EFI_ERROR_UNRECOVERED),
+ (EFI_PERIPHERAL_RECOVERY_MEDIA | EFI_P_EC_MEDIA_NOT_PRESENT)
+ );
+
+ } else {
+ ReportStatusCode (
+ (EFI_ERROR_CODE | EFI_ERROR_UNRECOVERED),
+ (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEIM_EC_NO_RECOVERY_CAPSULE)
+ );
+ }*/
+ //
+ // Hang.
+ //
+ CpuDeadLoop();
+}
+
+#define MAX_BLOCK_IO_PPI 32
+
+/*
+ CheckIfMediaPresentOnBlockIoDevice:
+ Checks to see whether there was a media device error or to see if there is media present.
+*/
+VOID
+CheckIfMediaPresentOnBlockIoDevice (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN OUT BOOLEAN *MediaDeviceError,
+ IN OUT BOOLEAN *MediaPresent
+ )
+{
+ EFI_STATUS Status;
+ UINTN BlockIoPpiInstance;
+ EFI_PEI_RECOVERY_BLOCK_IO_PPI *BlockIoPpi;
+ UINTN NumberBlockDevices;
+ EFI_PEI_BLOCK_IO_MEDIA Media;
+
+ *MediaDeviceError = TRUE;
+ *MediaPresent = FALSE;
+
+ for (BlockIoPpiInstance = 0; BlockIoPpiInstance < MAX_BLOCK_IO_PPI; BlockIoPpiInstance++) {
+ Status = PeiServicesLocatePpi (
+ &gEfiPeiVirtualBlockIoPpiGuid,
+ BlockIoPpiInstance,
+ NULL,
+ (VOID **)&BlockIoPpi
+ );
+ if (EFI_ERROR (Status)) {
+ //
+ // Done with all Block Io Ppis
+ //
+ break;
+ }
+
+ Status = BlockIoPpi->GetNumberOfBlockDevices (
+ PeiServices,
+ BlockIoPpi,
+ &NumberBlockDevices
+ );
+ if (EFI_ERROR (Status) || (NumberBlockDevices == 0)) {
+ continue;
+ }
+ //
+ // Just retrieve the first block
+ //
+ Status = BlockIoPpi->GetBlockDeviceMediaInfo (
+ PeiServices,
+ BlockIoPpi,
+ 0,
+ &Media
+ );
+ if (!EFI_ERROR (Status)) {
+ *MediaDeviceError = FALSE;
+ if (Media.MediaPresent) {
+ *MediaPresent = TRUE;
+ break;
+ }
+ }
+ }
+}
+
+VOID
+AssertMediaDeviceError (
+ IN EFI_PEI_SERVICES **PeiServices
+ )
+{
+/* ReportStatusCode (
+ (EFI_ERROR_CODE | EFI_ERROR_UNRECOVERED),
+ (EFI_PERIPHERAL_RECOVERY_MEDIA | EFI_P_EC_MEDIA_DEVICE_ERROR)
+ );
+*/
+ CpuDeadLoop ();
+}
+
+VOID
+ReportLoadCapsuleSuccess (
+ IN EFI_PEI_SERVICES **PeiServices
+ )
+{
+ //
+ // EFI_SW_PEI_PC_CAPSULE_START: (from the status code spec):
+ // Loaded the recovery capsule. About to hand off control to the capsule.
+ //
+/* ReportStatusCode (
+ EFI_PROGRESS_CODE,
+ (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEIM_PC_CAPSULE_LOAD_SUCCESS)
+ );*/
+}
+
diff --git a/QuarkPlatformPkg/Platform/Pei/PlatformInit/MemoryCallback.c b/QuarkPlatformPkg/Platform/Pei/PlatformInit/MemoryCallback.c
new file mode 100644
index 0000000000..728e2b1f6b
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Pei/PlatformInit/MemoryCallback.c
@@ -0,0 +1,237 @@
+/** @file
+This file includes a memory call back function notified when MRC is done,
+following action is performed in this file,
+ 1. ICH initialization after MRC.
+ 2. SIO initialization.
+ 3. Install ResetSystem and FinvFv PPI.
+ 4. Set MTRR for PEI
+ 5. Create FV HOB and Flash HOB
+
+Copyright (c) 2013 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+
+#include "CommonHeader.h"
+
+#include "PlatformEarlyInit.h"
+
+extern EFI_PEI_PPI_DESCRIPTOR mPpiStall[];
+
+EFI_PEI_RESET_PPI mResetPpi = { ResetSystem };
+
+EFI_PEI_PPI_DESCRIPTOR mPpiList[1] = {
+ {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiPeiResetPpiGuid,
+ &mResetPpi
+ }
+};
+
+/**
+ This function reset the entire platform, including all processor and devices, and
+ reboots the system.
+
+ @param PeiServices General purpose services available to every PEIM.
+
+ @retval EFI_SUCCESS if it completed successfully.
+**/
+EFI_STATUS
+EFIAPI
+ResetSystem (
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ ResetCold();
+ return EFI_SUCCESS;
+}
+
+/**
+ This function provides a blocking stall for reset at least the given number of microseconds
+ stipulated in the final argument.
+
+ @param PeiServices General purpose services available to every PEIM.
+
+ @param this Pointer to the local data for the interface.
+
+ @param Microseconds number of microseconds for which to stall.
+
+ @retval EFI_SUCCESS the function provided at least the required stall.
+**/
+EFI_STATUS
+EFIAPI
+Stall (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_STALL_PPI *This,
+ IN UINTN Microseconds
+ )
+{
+ MicroSecondDelay (Microseconds);
+ return EFI_SUCCESS;
+}
+
+
+/**
+ This function will be called when MRC is done.
+
+ @param PeiServices General purpose services available to every PEIM.
+
+ @param NotifyDescriptor Information about the notify event..
+
+ @param Ppi The notify context.
+
+ @retval EFI_SUCCESS If the function completed successfully.
+**/
+EFI_STATUS
+EFIAPI
+MemoryDiscoveredPpiNotifyCallback (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ )
+{
+ EFI_STATUS Status;
+ EFI_BOOT_MODE BootMode;
+ UINT64 MemoryLength;
+ EFI_SMRAM_DESCRIPTOR *SmramDescriptor;
+ UINTN NumSmramRegions;
+ UINT32 RmuMainBaseAddress;
+ UINT32 RegData32;
+ UINT8 CpuAddressWidth;
+ UINT32 RegEax;
+ MTRR_SETTINGS MtrrSettings;
+
+ DEBUG ((EFI_D_INFO, "Platform PEIM Memory Callback\n"));
+
+ NumSmramRegions = 0;
+ SmramDescriptor = NULL;
+ RmuMainBaseAddress = 0;
+
+ PERF_START (NULL, "SetCache", NULL, 0);
+
+ InfoPostInstallMemory (&RmuMainBaseAddress, &SmramDescriptor, &NumSmramRegions);
+ ASSERT (SmramDescriptor != NULL);
+ ASSERT (RmuMainBaseAddress != 0);
+
+ MemoryLength = ((UINT64) RmuMainBaseAddress) + 0x10000;
+
+ Status = PeiServicesGetBootMode (&BootMode);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Get current MTRR settings
+ //
+ MtrrGetAllMtrrs (&MtrrSettings);
+
+ //
+ // Set all DRAM cachability to CacheWriteBack
+ //
+ Status = MtrrSetMemoryAttributeInMtrrSettings (&MtrrSettings, 0, MemoryLength, CacheWriteBack);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // RTC:28208 - System hang/crash when entering probe mode(ITP) when relocating SMBASE
+ // Workaround to make default SMRAM UnCachable
+ //
+ Status = MtrrSetMemoryAttributeInMtrrSettings (&MtrrSettings, 0x30000, SIZE_64KB, CacheUncacheable);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Set new MTRR settings
+ //
+ MtrrSetAllMtrrs (&MtrrSettings);
+
+ PERF_END (NULL, "SetCache", NULL, 0);
+
+ //
+ // Install PeiReset for PeiResetSystem service
+ //
+ Status = PeiServicesInstallPpi (&mPpiList[0]);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Do QNC initialization after MRC
+ //
+ PeiQNCPostMemInit ();
+
+ Status = PeiServicesInstallPpi (&mPpiStall[0]);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Set E000/F000 Routing
+ //
+ RegData32 = QNCPortRead (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QNC_MSG_FSBIC_REG_HMISC);
+ RegData32 |= (BIT2|BIT1);
+ QNCPortWrite (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QNC_MSG_FSBIC_REG_HMISC, RegData32);
+
+ if (BootMode == BOOT_IN_RECOVERY_MODE) {
+ Status = PeimInitializeRecovery (PeiServices);
+ ASSERT_EFI_ERROR (Status);
+ } else if (BootMode == BOOT_ON_S3_RESUME) {
+ return EFI_SUCCESS;
+ } else {
+ PeiServicesInstallFvInfoPpi (
+ NULL,
+ (VOID *) (UINTN) PcdGet32 (PcdFlashFvMainBase),
+ PcdGet32 (PcdFlashFvMainSize),
+ NULL,
+ NULL
+ );
+
+ //
+ // Publish the FVMAIN FV so the DXE Phase can dispatch drivers from this FV
+ // and produce Load File Protocols for UEFI Applications in this FV.
+ //
+ BuildFvHob (
+ PcdGet32 (PcdFlashFvMainBase),
+ PcdGet32 (PcdFlashFvMainSize)
+ );
+
+ //
+ // Publish the Payload FV so the DXE Phase can dispatch drivers from this FV
+ // and produce Load File Protocols for UEFI Applications in this FV.
+ //
+ BuildFvHob (
+ PcdGet32 (PcdFlashFvPayloadBase),
+ PcdGet32 (PcdFlashFvPayloadSize)
+ );
+ }
+
+ //
+ // Build flash HOB, it's going to be used by GCD and E820 building
+ // Map full SPI flash decode range (regardless of smaller SPI flash parts installed)
+ //
+ BuildResourceDescriptorHob (
+ EFI_RESOURCE_FIRMWARE_DEVICE,
+ (EFI_RESOURCE_ATTRIBUTE_PRESENT |
+ EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+ EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
+ (SIZE_4GB - SIZE_8MB),
+ SIZE_8MB
+ );
+
+ //
+ // Create a CPU hand-off information
+ //
+ CpuAddressWidth = 32;
+ AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);
+ if (RegEax >= CPUID_VIR_PHY_ADDRESS_SIZE) {
+ AsmCpuid (CPUID_VIR_PHY_ADDRESS_SIZE, &RegEax, NULL, NULL, NULL);
+ CpuAddressWidth = (UINT8) (RegEax & 0xFF);
+ }
+ DEBUG ((EFI_D_INFO, "CpuAddressWidth: %d\n", CpuAddressWidth));
+
+ BuildCpuHob (CpuAddressWidth, 16);
+
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
diff --git a/QuarkPlatformPkg/Platform/Pei/PlatformInit/MrcWrapper.c b/QuarkPlatformPkg/Platform/Pei/PlatformInit/MrcWrapper.c
new file mode 100644
index 0000000000..eee696e0e7
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Pei/PlatformInit/MrcWrapper.c
@@ -0,0 +1,1641 @@
+/** @file
+Framework PEIM to initialize memory on a Quark Memory Controller.
+
+Copyright (c) 2013 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "CommonHeader.h"
+#include "MrcWrapper.h"
+#include <Ioh.h>
+#include "Platform.h"
+
+#include <Library/PlatformHelperLib.h>
+
+//
+// ------------------------ TSEG Base
+//
+// ------------------------ RESERVED_CPU_S3_SAVE_OFFSET
+// CPU S3 data
+// ------------------------ RESERVED_ACPI_S3_RANGE_OFFSET
+// S3 Memory base structure
+// ------------------------ TSEG + 1 page
+
+#define RESERVED_CPU_S3_SAVE_OFFSET (RESERVED_ACPI_S3_RANGE_OFFSET - sizeof (SMM_S3_RESUME_STATE))
+
+// Strap configuration register specifying DDR setup
+#define QUARK_SCSS_REG_STPDDRCFG 0x00
+
+// Macro counting array elements
+#define COUNT(a) (sizeof(a)/sizeof(*a))
+
+
+EFI_MEMORY_TYPE_INFORMATION mDefaultQncMemoryTypeInformation[] = {
+ { EfiReservedMemoryType, EDKII_RESERVED_SIZE_PAGES }, // BIOS Reserved
+ { EfiACPIMemoryNVS, ACPI_NVS_SIZE_PAGES }, // S3, SMM, etc
+ { EfiRuntimeServicesData, RUNTIME_SERVICES_DATA_SIZE_PAGES },
+ { EfiRuntimeServicesCode, RUNTIME_SERVICES_CODE_SIZE_PAGES },
+ { EfiACPIReclaimMemory, ACPI_RECLAIM_SIZE_PAGES }, // ACPI ASL
+ { EfiMaxMemoryType, 0 }
+};
+
+/**
+ Configure Uart mmio base for MRC serial log purpose
+
+ @param MrcData - MRC configuration data updated
+
+**/
+VOID
+MrcUartConfig(
+ MRC_PARAMS *MrcData
+ )
+{
+ UINT8 UartIdx;
+ UINT32 RegData32;
+ UINT8 IohUartBus;
+ UINT8 IohUartDev;
+
+ UartIdx = PcdGet8(PcdIohUartFunctionNumber);
+ IohUartBus = PcdGet8(PcdIohUartBusNumber);
+ IohUartDev = PcdGet8(PcdIohUartDevNumber);
+
+ RegData32 = PciRead32 (PCI_LIB_ADDRESS(IohUartBus, IohUartDev, UartIdx, PCI_BASE_ADDRESSREG_OFFSET));
+ MrcData->uart_mmio_base = RegData32 & 0xFFFFFFF0;
+}
+
+/**
+ Configure MRC from memory controller fuse settings.
+
+ @param MrcData - MRC configuration data to be updated.
+
+ @return EFI_SUCCESS MRC Config parameters updated from platform data.
+**/
+EFI_STATUS
+MrcConfigureFromMcFuses (
+ OUT MRC_PARAMS *MrcData
+ )
+{
+ UINT32 McFuseStat;
+
+ McFuseStat = QNCPortRead (
+ QUARK_NC_MEMORY_CONTROLLER_SB_PORT_ID,
+ QUARK_NC_MEMORY_CONTROLLER_REG_DFUSESTAT
+ );
+
+ DEBUG ((EFI_D_INFO, "MRC McFuseStat 0x%08x\n", McFuseStat));
+
+ if ((McFuseStat & B_DFUSESTAT_ECC_DIS) != 0) {
+ DEBUG ((EFI_D_INFO, "MRC Fuse : fus_dun_ecc_dis.\n"));
+ MrcData->ecc_enables = 0;
+ } else {
+ MrcData->ecc_enables = 1;
+ }
+ return EFI_SUCCESS;
+}
+
+/**
+ Configure MRC from platform info hob.
+
+ @param MrcData - MRC configuration data to be updated.
+
+ @return EFI_SUCCESS MRC Config parameters updated from hob.
+ @return EFI_NOT_FOUND Platform Info or MRC Config parameters not found.
+ @return EFI_INVALID_PARAMETER Wrong params in hob.
+**/
+EFI_STATUS
+MrcConfigureFromInfoHob (
+ OUT MRC_PARAMS *MrcData
+ )
+{
+ PDAT_MRC_ITEM *ItemData;
+
+ ItemData = (PDAT_MRC_ITEM *)PcdGetPtr (PcdMrcParameters);
+
+ MrcData->channel_enables = ItemData->ChanMask;
+ MrcData->channel_width = ItemData->ChanWidth;
+ MrcData->address_mode = ItemData->AddrMode;
+ // Enable scrambling if requested.
+ MrcData->scrambling_enables = (ItemData->Flags & PDAT_MRC_FLAG_SCRAMBLE_EN) != 0;
+ MrcData->ddr_type = ItemData->DramType;
+ MrcData->dram_width = ItemData->DramWidth;
+ MrcData->ddr_speed = ItemData->DramSpeed;
+ // Enable ECC if requested.
+ MrcData->rank_enables = ItemData->RankMask;
+ MrcData->params.DENSITY = ItemData->DramDensity;
+ MrcData->params.tCL = ItemData->tCL;
+ MrcData->params.tRAS = ItemData->tRAS;
+ MrcData->params.tWTR = ItemData->tWTR;
+ MrcData->params.tRRD = ItemData->tRRD;
+ MrcData->params.tFAW = ItemData->tFAW;
+
+ MrcData->refresh_rate = ItemData->SrInt;
+ MrcData->sr_temp_range = ItemData->SrTemp;
+ MrcData->ron_value = ItemData->DramRonVal;
+ MrcData->rtt_nom_value = ItemData->DramRttNomVal;
+ MrcData->rd_odt_value = ItemData->SocRdOdtVal;
+
+ DEBUG ((EFI_D_INFO, "MRC dram_width %d\n", MrcData->dram_width));
+ DEBUG ((EFI_D_INFO, "MRC rank_enables %d\n",MrcData->rank_enables));
+ DEBUG ((EFI_D_INFO, "MRC ddr_speed %d\n", MrcData->ddr_speed));
+ DEBUG ((EFI_D_INFO, "MRC flags: %s\n",
+ (MrcData->scrambling_enables) ? L"SCRAMBLE_EN" : L""
+ ));
+
+ DEBUG ((EFI_D_INFO, "MRC density=%d tCL=%d tRAS=%d tWTR=%d tRRD=%d tFAW=%d\n",
+ MrcData->params.DENSITY,
+ MrcData->params.tCL,
+ MrcData->params.tRAS,
+ MrcData->params.tWTR,
+ MrcData->params.tRRD,
+ MrcData->params.tFAW
+ ));
+
+ return EFI_SUCCESS;
+}
+
+/**
+
+ Configure ECC scrub
+
+ @param MrcData - MRC configuration
+
+**/
+VOID
+EccScrubSetup(
+ const MRC_PARAMS *MrcData
+ )
+{
+ UINT32 BgnAdr = 0;
+ UINT32 EndAdr = MrcData->mem_size;
+ UINT32 BlkSize = PcdGet8(PcdEccScrubBlkSize) & SCRUB_CFG_BLOCKSIZE_MASK;
+ UINT32 Interval = PcdGet8(PcdEccScrubInterval) & SCRUB_CFG_INTERVAL_MASK;
+
+ if( MrcData->ecc_enables == 0 || MrcData->boot_mode == bmS3 || Interval == 0) {
+ // No scrub configuration needed if ECC not enabled
+ // On S3 resume reconfiguration is done as part of resume
+ // script, see SNCS3Save.c ==> SaveRuntimeScriptTable()
+ // Also if PCD disables scrub, then we do nothing.
+ return;
+ }
+
+ QNCPortWrite (QUARK_NC_RMU_SB_PORT_ID, QUARK_NC_ECC_SCRUB_END_MEM_REG, EndAdr);
+ QNCPortWrite (QUARK_NC_RMU_SB_PORT_ID, QUARK_NC_ECC_SCRUB_START_MEM_REG, BgnAdr);
+ QNCPortWrite (QUARK_NC_RMU_SB_PORT_ID, QUARK_NC_ECC_SCRUB_NEXT_READ_REG, BgnAdr);
+ QNCPortWrite (QUARK_NC_RMU_SB_PORT_ID, QUARK_NC_ECC_SCRUB_CONFIG_REG,
+ Interval << SCRUB_CFG_INTERVAL_SHIFT |
+ BlkSize << SCRUB_CFG_BLOCKSIZE_SHIFT);
+
+ McD0PciCfg32 (QNC_ACCESS_PORT_MCR) = SCRUB_RESUME_MSG();
+}
+
+/** Post InstallS3Memory / InstallEfiMemory tasks given MrcData context.
+
+ @param[in] MrcData MRC configuration.
+ @param[in] IsS3 TRUE if after InstallS3Memory.
+
+**/
+VOID
+PostInstallMemory (
+ IN MRC_PARAMS *MrcData,
+ IN BOOLEAN IsS3
+ )
+{
+ UINT32 RmuMainDestBaseAddress;
+ UINT32 *RmuMainSrcBaseAddress;
+ UINTN RmuMainSize;
+ EFI_STATUS Status;
+
+ //
+ // Setup ECC policy (All boot modes).
+ //
+ QNCPolicyDblEccBitErr (V_WDT_CONTROL_DBL_ECC_BIT_ERR_WARM);
+
+ //
+ // Find the 64KB of memory for Rmu Main at the top of available memory.
+ //
+ InfoPostInstallMemory (&RmuMainDestBaseAddress, NULL, NULL);
+ DEBUG ((EFI_D_INFO, "RmuMain Base Address : 0x%x\n", RmuMainDestBaseAddress));
+
+ //
+ // Relocate RmuMain.
+ //
+ if (IsS3) {
+ QNCSendOpcodeDramReady (RmuMainDestBaseAddress);
+ } else {
+ Status = PlatformFindFvFileRawDataSection (NULL, PcdGetPtr(PcdQuarkMicrocodeFile), (VOID **) &RmuMainSrcBaseAddress, &RmuMainSize);
+ ASSERT_EFI_ERROR (Status);
+ if (!EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_INFO, "Found Microcode ADDR:SIZE 0x%08x:0x%04x\n", (UINTN) RmuMainSrcBaseAddress, RmuMainSize));
+ }
+
+ RmuMainRelocation (RmuMainDestBaseAddress, (UINT32) RmuMainSrcBaseAddress, RmuMainSize);
+ QNCSendOpcodeDramReady (RmuMainDestBaseAddress);
+ EccScrubSetup (MrcData);
+ }
+}
+
+/**
+
+ Do memory initialisation for QNC DDR3 SDRAM Controller
+
+ @param FfsHeader Not used.
+ @param PeiServices General purpose services available to every PEIM.
+
+ @return EFI_SUCCESS Memory initialisation completed successfully.
+ All other error conditions encountered result in an ASSERT.
+
+**/
+EFI_STATUS
+MemoryInit (
+ IN EFI_PEI_SERVICES **PeiServices
+ )
+{
+ MRC_PARAMS MrcData;
+ EFI_BOOT_MODE BootMode;
+ EFI_STATUS Status;
+ EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariableServices;
+ EFI_STATUS_CODE_VALUE ErrorCodeValue;
+ PEI_QNC_MEMORY_INIT_PPI *QncMemoryInitPpi;
+ UINT16 PmswAdr;
+
+ ErrorCodeValue = 0;
+
+ //
+ // It is critical that both of these data structures are initialized to 0.
+ // This PEIM knows the number of DIMMs in the system and works with that
+ // information. The MCH PEIM that consumes these data structures does not
+ // know the number of DIMMs so it expects the entire structure to be
+ // properly initialized. By initializing these to zero, all flags indicating
+ // that the SPD is present or the row should be configured are set to false.
+ //
+ ZeroMem (&MrcData, sizeof(MrcData));
+
+ //
+ // Get necessary PPI
+ //
+ Status = PeiServicesLocatePpi (
+ &gEfiPeiReadOnlyVariable2PpiGuid, // GUID
+ 0, // INSTANCE
+ NULL, // EFI_PEI_PPI_DESCRIPTOR
+ (VOID **)&VariableServices // PPI
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Determine boot mode
+ //
+ Status = PeiServicesGetBootMode (&BootMode);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Initialize Error type for reporting status code
+ //
+ switch (BootMode) {
+ case BOOT_ON_FLASH_UPDATE:
+ ErrorCodeValue = EFI_COMPUTING_UNIT_MEMORY + EFI_CU_MEMORY_EC_UPDATE_FAIL;
+ break;
+ case BOOT_ON_S3_RESUME:
+ ErrorCodeValue = EFI_COMPUTING_UNIT_MEMORY + EFI_CU_MEMORY_EC_S3_RESUME_FAIL;
+ break;
+ default:
+ ErrorCodeValue = EFI_COMPUTING_UNIT_MEMORY;
+ break;
+ }
+
+ //
+ // Specify MRC boot mode
+ //
+ switch (BootMode) {
+ case BOOT_ON_S3_RESUME:
+ case BOOT_ON_FLASH_UPDATE:
+ MrcData.boot_mode = bmS3;
+ break;
+ case BOOT_ASSUMING_NO_CONFIGURATION_CHANGES:
+ MrcData.boot_mode = bmFast;
+ break;
+ default:
+ MrcData.boot_mode = bmCold;
+ break;
+ }
+
+ //
+ // Configure MRC input parameters.
+ //
+ Status = MrcConfigureFromMcFuses (&MrcData);
+ ASSERT_EFI_ERROR (Status);
+ Status = MrcConfigureFromInfoHob (&MrcData);
+ ASSERT_EFI_ERROR (Status);
+ MrcUartConfig(&MrcData);
+
+ if (BootMode == BOOT_IN_RECOVERY_MODE) {
+ //
+ // Always do bmCold on recovery.
+ //
+ DEBUG ((DEBUG_INFO, "MemoryInit:Force bmCold on Recovery\n"));
+ MrcData.boot_mode = bmCold;
+ } else {
+
+ //
+ // Load Memory configuration data saved in previous boot from variable
+ //
+ Status = LoadConfig (
+ PeiServices,
+ VariableServices,
+ &MrcData
+ );
+
+ if (EFI_ERROR (Status)) {
+
+ switch (BootMode) {
+ case BOOT_ON_S3_RESUME:
+ case BOOT_ON_FLASH_UPDATE:
+ REPORT_STATUS_CODE (
+ EFI_ERROR_CODE + EFI_ERROR_UNRECOVERED,
+ ErrorCodeValue
+ );
+ PeiServicesResetSystem ();
+ break;
+
+ default:
+ MrcData.boot_mode = bmCold;
+ break;
+ }
+ }
+ }
+
+ //
+ // Locate Memory Reference Code PPI
+ //
+ Status = PeiServicesLocatePpi (
+ &gQNCMemoryInitPpiGuid, // GUID
+ 0, // INSTANCE
+ NULL, // EFI_PEI_PPI_DESCRIPTOR
+ (VOID **)&QncMemoryInitPpi // PPI
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ PmswAdr = (UINT16)(LpcPciCfg32 (R_QNC_LPC_GPE0BLK) & 0xFFFF) + R_QNC_GPE0BLK_PMSW;
+ if( IoRead32 (PmswAdr) & B_QNC_GPE0BLK_PMSW_DRAM_INIT) {
+ // MRC did not complete last execution, force cold boot path
+ MrcData.boot_mode = bmCold;
+ }
+
+ // Mark MRC pending
+ IoOr32 (PmswAdr, (UINT32)B_QNC_GPE0BLK_PMSW_DRAM_INIT);
+
+ //
+ // Call Memory Reference Code's Routines
+ //
+ QncMemoryInitPpi->MrcStart (&MrcData);
+
+ // Mark MRC completed
+ IoAnd32 (PmswAdr, ~(UINT32)B_QNC_GPE0BLK_PMSW_DRAM_INIT);
+
+
+ //
+ // Note emulation platform has to read actual memory size
+ // MrcData.mem_size from PcdGet32 (PcdMemorySize);
+
+ if (BootMode == BOOT_ON_S3_RESUME) {
+
+ DEBUG ((EFI_D_INFO, "Following BOOT_ON_S3_RESUME boot path.\n"));
+
+ Status = InstallS3Memory (PeiServices, VariableServices, MrcData.mem_size);
+ if (EFI_ERROR (Status)) {
+ REPORT_STATUS_CODE (
+ EFI_ERROR_CODE + EFI_ERROR_UNRECOVERED,
+ ErrorCodeValue
+ );
+ PeiServicesResetSystem ();
+ }
+ PostInstallMemory (&MrcData, TRUE);
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Assign physical memory to PEI and DXE
+ //
+ DEBUG ((EFI_D_INFO, "InstallEfiMemory.\n"));
+
+ Status = InstallEfiMemory (
+ PeiServices,
+ VariableServices,
+ BootMode,
+ MrcData.mem_size
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ PostInstallMemory (&MrcData, FALSE);
+
+ //
+ // Save current configuration into Hob and will save into Variable later in DXE
+ //
+ DEBUG ((EFI_D_INFO, "SaveConfig.\n"));
+ Status = SaveConfig (
+ &MrcData
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ DEBUG ((EFI_D_INFO, "MemoryInit Complete.\n"));
+
+ return EFI_SUCCESS;
+}
+
+/**
+
+ This function saves a config to a HOB.
+
+ @param RowInfo The MCH row configuration information.
+ @param TimingData Timing data to be saved.
+ @param RowConfArray Row configuration information for each row in the system.
+ @param SpdData SPD info read for each DIMM slot in the system.
+
+ @return EFI_SUCCESS: The function completed successfully.
+
+**/
+EFI_STATUS
+SaveConfig (
+ IN MRC_PARAMS *MrcData
+ )
+{
+ //
+ // Build HOB data for Memory Config
+ // HOB data size (stored in variable) is required to be multiple of 8 bytes
+ //
+ BuildGuidDataHob (
+ &gEfiMemoryConfigDataGuid,
+ (VOID *) &MrcData->timings,
+ ((sizeof (MrcData->timings) + 0x7) & (~0x7))
+ );
+
+ DEBUG ((EFI_D_INFO, "IIO IoApicBase = %x IoApicLimit=%x\n", IOAPIC_BASE, (IOAPIC_BASE + IOAPIC_SIZE - 1)));
+ DEBUG ((EFI_D_INFO, "IIO RcbaAddress = %x\n", (UINT32)PcdGet64 (PcdRcbaMmioBaseAddress)));
+
+ return EFI_SUCCESS;
+}
+
+/**
+
+ Load a configuration stored in a variable.
+
+ @param TimingData Timing data to be loaded from NVRAM.
+ @param RowConfArray Row configuration information for each row in the system.
+
+ @return EFI_SUCCESS The function completed successfully.
+ Other Could not read variable.
+
+**/
+EFI_STATUS
+LoadConfig (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariableServices,
+ IN OUT MRC_PARAMS *MrcData
+ )
+{
+ EFI_STATUS Status;
+ UINTN BufferSize;
+ PLATFORM_VARIABLE_MEMORY_CONFIG_DATA VarData;
+
+ BufferSize = ((sizeof (VarData.timings) + 0x7) & (~0x7)); // HOB data size (stored in variable) is required to be multiple of 8bytes
+
+ Status = VariableServices->GetVariable (
+ VariableServices,
+ EFI_MEMORY_CONFIG_DATA_NAME,
+ &gEfiMemoryConfigDataGuid,
+ NULL,
+ &BufferSize,
+ &VarData.timings
+ );
+ if (!EFI_ERROR (Status)) {
+ CopyMem (&MrcData->timings, &VarData.timings, sizeof(MrcData->timings));
+ }
+ return Status;
+}
+
+/**
+
+ This function installs memory.
+
+ @param PeiServices PEI Services table.
+ @param BootMode The specific boot path that is being followed
+ @param Mch Pointer to the DualChannelDdrMemoryInit PPI
+ @param RowConfArray Row configuration information for each row in the system.
+
+ @return EFI_SUCCESS The function completed successfully.
+ EFI_INVALID_PARAMETER One of the input parameters was invalid.
+ EFI_ABORTED An error occurred.
+
+**/
+EFI_STATUS
+InstallEfiMemory (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariableServices,
+ IN EFI_BOOT_MODE BootMode,
+ IN UINT32 TotalMemorySize
+ )
+{
+ EFI_PHYSICAL_ADDRESS PeiMemoryBaseAddress;
+ EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *SmramHobDescriptorBlock;
+ EFI_STATUS Status;
+ EFI_PEI_HOB_POINTERS Hob;
+ PEI_DUAL_CHANNEL_DDR_MEMORY_MAP_RANGE MemoryMap[MAX_RANGES];
+ UINT8 Index;
+ UINT8 NumRanges;
+ UINT8 SmramIndex;
+ UINT8 SmramRanges;
+ UINT64 PeiMemoryLength;
+ UINTN BufferSize;
+ UINTN PeiMemoryIndex;
+ UINTN RequiredMemSize;
+ EFI_RESOURCE_ATTRIBUTE_TYPE Attribute;
+ EFI_PHYSICAL_ADDRESS BadMemoryAddress;
+ EFI_SMRAM_DESCRIPTOR DescriptorAcpiVariable;
+ VOID *CapsuleBuffer;
+ UINTN CapsuleBufferLength;
+ PEI_CAPSULE_PPI *Capsule;
+ VOID *LargeMemRangeBuf;
+ UINTN LargeMemRangeBufLen;
+
+ //
+ // Test the memory from 1M->TOM
+ //
+ if (BootMode != BOOT_ON_FLASH_UPDATE) {
+ Status = BaseMemoryTest (
+ PeiServices,
+ 0x100000,
+ (TotalMemorySize - 0x100000),
+ Quick,
+ &BadMemoryAddress
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+
+
+ //
+ // Get the Memory Map
+ //
+ NumRanges = MAX_RANGES;
+
+ ZeroMem (MemoryMap, sizeof (PEI_DUAL_CHANNEL_DDR_MEMORY_MAP_RANGE) * NumRanges);
+
+ Status = GetMemoryMap (
+ PeiServices,
+ TotalMemorySize,
+ (PEI_DUAL_CHANNEL_DDR_MEMORY_MAP_RANGE *) MemoryMap,
+ &NumRanges
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Find the highest memory range in processor native address space to give to
+ // PEI. Then take the top.
+ //
+ PeiMemoryBaseAddress = 0;
+
+ //
+ // Query the platform for the minimum memory size
+ //
+
+ Status = GetPlatformMemorySize (
+ PeiServices,
+ BootMode,
+ &PeiMemoryLength
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Get required memory size for ACPI use. This helps to put ACPI memory on the topest
+ //
+ RequiredMemSize = 0;
+ RetriveRequiredMemorySize (PeiServices, &RequiredMemSize);
+
+ PeiMemoryIndex = 0;
+
+ for (Index = 0; Index < NumRanges; Index++)
+ {
+ DEBUG ((EFI_D_INFO, "Found 0x%x bytes at ", MemoryMap[Index].RangeLength));
+ DEBUG ((EFI_D_INFO, "0x%x.\n", MemoryMap[Index].PhysicalAddress));
+
+ if ((MemoryMap[Index].Type == DualChannelDdrMainMemory) &&
+ (MemoryMap[Index].PhysicalAddress + MemoryMap[Index].RangeLength < MAX_ADDRESS) &&
+ (MemoryMap[Index].PhysicalAddress >= PeiMemoryBaseAddress) &&
+ (MemoryMap[Index].RangeLength >= PeiMemoryLength)) {
+ PeiMemoryBaseAddress = MemoryMap[Index].PhysicalAddress +
+ MemoryMap[Index].RangeLength -
+ PeiMemoryLength;
+ PeiMemoryIndex = Index;
+ }
+ }
+
+ //
+ // Find the largest memory range excluding that given to PEI.
+ //
+ LargeMemRangeBuf = NULL;
+ LargeMemRangeBufLen = 0;
+ for (Index = 0; Index < NumRanges; Index++) {
+ if ((MemoryMap[Index].Type == DualChannelDdrMainMemory) &&
+ (MemoryMap[Index].PhysicalAddress + MemoryMap[Index].RangeLength < MAX_ADDRESS)) {
+ if (Index != PeiMemoryIndex) {
+ if (MemoryMap[Index].RangeLength > LargeMemRangeBufLen) {
+ LargeMemRangeBuf = (VOID *) ((UINTN) MemoryMap[Index].PhysicalAddress);
+ LargeMemRangeBufLen = (UINTN) MemoryMap[Index].RangeLength;
+ }
+ } else {
+ if ((MemoryMap[Index].RangeLength - PeiMemoryLength) >= LargeMemRangeBufLen) {
+ LargeMemRangeBuf = (VOID *) ((UINTN) MemoryMap[Index].PhysicalAddress);
+ LargeMemRangeBufLen = (UINTN) (MemoryMap[Index].RangeLength - PeiMemoryLength);
+ }
+ }
+ }
+ }
+
+ Capsule = NULL;
+ CapsuleBuffer = NULL;
+ CapsuleBufferLength = 0;
+ if (BootMode == BOOT_ON_FLASH_UPDATE) {
+ Status = PeiServicesLocatePpi (
+ &gPeiCapsulePpiGuid, // GUID
+ 0, // INSTANCE
+ NULL, // EFI_PEI_PPI_DESCRIPTOR
+ (VOID **)&Capsule // PPI
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ if (Status == EFI_SUCCESS) {
+ CapsuleBuffer = LargeMemRangeBuf;
+ CapsuleBufferLength = LargeMemRangeBufLen;
+
+ //
+ // Call the Capsule PPI Coalesce function to coalesce the capsule data.
+ //
+ Status = Capsule->Coalesce (
+ PeiServices,
+ &CapsuleBuffer,
+ &CapsuleBufferLength
+ );
+ //
+ // If it failed, then NULL out our capsule PPI pointer so that the capsule
+ // HOB does not get created below.
+ //
+ if (Status != EFI_SUCCESS) {
+ Capsule = NULL;
+ }
+ }
+ }
+
+ //
+ // Set up the IMR policy required for this platform
+ //
+ Status = SetPlatformImrPolicy (
+ PeiMemoryBaseAddress,
+ PeiMemoryLength,
+ RequiredMemSize
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Carve out the top memory reserved for ACPI
+ //
+ Status = PeiServicesInstallPeiMemory (PeiMemoryBaseAddress, (PeiMemoryLength - RequiredMemSize));
+ ASSERT_EFI_ERROR (Status);
+
+ BuildResourceDescriptorHob (
+ EFI_RESOURCE_SYSTEM_MEMORY, // MemoryType,
+ (
+ EFI_RESOURCE_ATTRIBUTE_PRESENT |
+ EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+ EFI_RESOURCE_ATTRIBUTE_TESTED |
+ EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
+ EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
+ EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
+ EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
+ ),
+ PeiMemoryBaseAddress, // MemoryBegin
+ PeiMemoryLength // MemoryLength
+ );
+
+ //
+ // Install physical memory descriptor hobs for each memory range.
+ //
+ SmramRanges = 0;
+ for (Index = 0; Index < NumRanges; Index++) {
+ Attribute = 0;
+ if (MemoryMap[Index].Type == DualChannelDdrMainMemory)
+ {
+ if (Index == PeiMemoryIndex) {
+ //
+ // This is a partially tested Main Memory range, give it to EFI
+ //
+ BuildResourceDescriptorHob (
+ EFI_RESOURCE_SYSTEM_MEMORY,
+ (
+ EFI_RESOURCE_ATTRIBUTE_PRESENT |
+ EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+ EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
+ EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
+ EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
+ EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
+ ),
+ MemoryMap[Index].PhysicalAddress,
+ MemoryMap[Index].RangeLength - PeiMemoryLength
+ );
+ } else {
+ //
+ // This is an untested Main Memory range, give it to EFI
+ //
+ BuildResourceDescriptorHob (
+ EFI_RESOURCE_SYSTEM_MEMORY, // MemoryType,
+ (
+ EFI_RESOURCE_ATTRIBUTE_PRESENT |
+ EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+ EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
+ EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
+ EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
+ EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
+ ),
+ MemoryMap[Index].PhysicalAddress, // MemoryBegin
+ MemoryMap[Index].RangeLength // MemoryLength
+ );
+ }
+ } else {
+ if ((MemoryMap[Index].Type == DualChannelDdrSmramCacheable) ||
+ (MemoryMap[Index].Type == DualChannelDdrSmramNonCacheable)) {
+ SmramRanges++;
+ }
+ if ((MemoryMap[Index].Type == DualChannelDdrSmramNonCacheable) ||
+ (MemoryMap[Index].Type == DualChannelDdrGraphicsMemoryNonCacheable)) {
+ Attribute |= EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE;
+ }
+ if ((MemoryMap[Index].Type == DualChannelDdrSmramCacheable) ||
+ (MemoryMap[Index].Type == DualChannelDdrGraphicsMemoryCacheable)) {
+ //
+ // TSEG and HSEG can be used with a write-back(WB) cache policy; however,
+ // the specification requires that the TSEG and HSEG space be cached only
+ // inside of the SMI handler. when using HSEG or TSEG an IA-32 processor
+ // does not automatically write back and invalidate its cache before entering
+ // SMM or before existing SMM therefore any MTRR defined for the active TSEG
+ // or HSEG must be set to un-cacheable(UC) outside of SMM.
+ //
+ Attribute |= EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE;
+ }
+ if (MemoryMap[Index].Type == DualChannelDdrReservedMemory) {
+ Attribute |= EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |
+ EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE;
+ }
+ //
+ // Make sure non-system memory is marked as reserved
+ //
+ BuildResourceDescriptorHob (
+ EFI_RESOURCE_MEMORY_RESERVED, // MemoryType,
+ Attribute, // MemoryAttribute
+ MemoryMap[Index].PhysicalAddress, // MemoryBegin
+ MemoryMap[Index].RangeLength // MemoryLength
+ );
+ }
+ }
+
+ //
+ // Allocate one extra EFI_SMRAM_DESCRIPTOR to describe a page of SMRAM memory that contains a pointer
+ // to the SMM Services Table that is required on the S3 resume path
+ //
+ ASSERT (SmramRanges > 0);
+ BufferSize = sizeof (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK);
+ BufferSize += ((SmramRanges - 1) * sizeof (EFI_SMRAM_DESCRIPTOR));
+
+ Hob.Raw = BuildGuidHob (
+ &gEfiSmmPeiSmramMemoryReserveGuid,
+ BufferSize
+ );
+ ASSERT (Hob.Raw);
+
+ SmramHobDescriptorBlock = (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *) (Hob.Raw);
+ SmramHobDescriptorBlock->NumberOfSmmReservedRegions = SmramRanges;
+
+ SmramIndex = 0;
+ for (Index = 0; Index < NumRanges; Index++) {
+ if ((MemoryMap[Index].Type == DualChannelDdrSmramCacheable) ||
+ (MemoryMap[Index].Type == DualChannelDdrSmramNonCacheable)
+ ) {
+ //
+ // This is an SMRAM range, create an SMRAM descriptor
+ //
+ SmramHobDescriptorBlock->Descriptor[SmramIndex].PhysicalStart = MemoryMap[Index].PhysicalAddress;
+ SmramHobDescriptorBlock->Descriptor[SmramIndex].CpuStart = MemoryMap[Index].CpuAddress;
+ SmramHobDescriptorBlock->Descriptor[SmramIndex].PhysicalSize = MemoryMap[Index].RangeLength;
+ if (MemoryMap[Index].Type == DualChannelDdrSmramCacheable) {
+ SmramHobDescriptorBlock->Descriptor[SmramIndex].RegionState = EFI_SMRAM_CLOSED | EFI_CACHEABLE;
+ } else {
+ SmramHobDescriptorBlock->Descriptor[SmramIndex].RegionState = EFI_SMRAM_CLOSED;
+ }
+
+ SmramIndex++;
+ }
+ }
+
+ //
+ // Build a HOB with the location of the reserved memory range.
+ //
+ CopyMem(&DescriptorAcpiVariable, &SmramHobDescriptorBlock->Descriptor[SmramRanges-1], sizeof(EFI_SMRAM_DESCRIPTOR));
+ DescriptorAcpiVariable.CpuStart += RESERVED_CPU_S3_SAVE_OFFSET;
+ BuildGuidDataHob (
+ &gEfiAcpiVariableGuid,
+ &DescriptorAcpiVariable,
+ sizeof (EFI_SMRAM_DESCRIPTOR)
+ );
+
+ //
+ // If we found the capsule PPI (and we didn't have errors), then
+ // call the capsule PEIM to allocate memory for the capsule.
+ //
+ if (Capsule != NULL) {
+ Status = Capsule->CreateState (PeiServices, CapsuleBuffer, CapsuleBufferLength);
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+
+ Find memory that is reserved so PEI has some to use.
+
+ @param PeiServices PEI Services table.
+ @param VariableSevices Variable PPI instance.
+
+ @return EFI_SUCCESS The function completed successfully.
+ Error value from LocatePpi()
+ Error Value from VariableServices->GetVariable()
+
+**/
+EFI_STATUS
+InstallS3Memory (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariableServices,
+ IN UINT32 TotalMemorySize
+ )
+{
+ EFI_STATUS Status;
+ UINTN S3MemoryBase;
+ UINTN S3MemorySize;
+ UINT8 SmramRanges;
+ UINT8 NumRanges;
+ UINT8 Index;
+ UINT8 SmramIndex;
+ UINTN BufferSize;
+ EFI_PEI_HOB_POINTERS Hob;
+ EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *SmramHobDescriptorBlock;
+ PEI_DUAL_CHANNEL_DDR_MEMORY_MAP_RANGE MemoryMap[MAX_RANGES];
+ RESERVED_ACPI_S3_RANGE *S3MemoryRangeData;
+ EFI_SMRAM_DESCRIPTOR DescriptorAcpiVariable;
+
+ //
+ // Get the Memory Map
+ //
+ NumRanges = MAX_RANGES;
+
+ ZeroMem (MemoryMap, sizeof (PEI_DUAL_CHANNEL_DDR_MEMORY_MAP_RANGE) * NumRanges);
+
+ Status = GetMemoryMap (
+ PeiServices,
+ TotalMemorySize,
+ (PEI_DUAL_CHANNEL_DDR_MEMORY_MAP_RANGE *) MemoryMap,
+ &NumRanges
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Install physical memory descriptor hobs for each memory range.
+ //
+ SmramRanges = 0;
+ for (Index = 0; Index < NumRanges; Index++) {
+ if ((MemoryMap[Index].Type == DualChannelDdrSmramCacheable) ||
+ (MemoryMap[Index].Type == DualChannelDdrSmramNonCacheable)) {
+ SmramRanges++;
+ }
+ }
+
+ ASSERT (SmramRanges > 0);
+
+ //
+ // Allocate one extra EFI_SMRAM_DESCRIPTOR to describe a page of SMRAM memory that contains a pointer
+ // to the SMM Services Table that is required on the S3 resume path
+ //
+ BufferSize = sizeof (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK);
+ if (SmramRanges > 0) {
+ BufferSize += ((SmramRanges - 1) * sizeof (EFI_SMRAM_DESCRIPTOR));
+ }
+
+ Hob.Raw = BuildGuidHob (
+ &gEfiSmmPeiSmramMemoryReserveGuid,
+ BufferSize
+ );
+ ASSERT (Hob.Raw);
+
+ SmramHobDescriptorBlock = (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *) (Hob.Raw);
+ SmramHobDescriptorBlock->NumberOfSmmReservedRegions = SmramRanges;
+
+ SmramIndex = 0;
+ for (Index = 0; Index < NumRanges; Index++) {
+ if ((MemoryMap[Index].Type == DualChannelDdrSmramCacheable) ||
+ (MemoryMap[Index].Type == DualChannelDdrSmramNonCacheable)
+ ) {
+ //
+ // This is an SMRAM range, create an SMRAM descriptor
+ //
+ SmramHobDescriptorBlock->Descriptor[SmramIndex].PhysicalStart = MemoryMap[Index].PhysicalAddress;
+ SmramHobDescriptorBlock->Descriptor[SmramIndex].CpuStart = MemoryMap[Index].CpuAddress;
+ SmramHobDescriptorBlock->Descriptor[SmramIndex].PhysicalSize = MemoryMap[Index].RangeLength;
+ if (MemoryMap[Index].Type == DualChannelDdrSmramCacheable) {
+ SmramHobDescriptorBlock->Descriptor[SmramIndex].RegionState = EFI_SMRAM_CLOSED | EFI_CACHEABLE;
+ } else {
+ SmramHobDescriptorBlock->Descriptor[SmramIndex].RegionState = EFI_SMRAM_CLOSED;
+ }
+
+ SmramIndex++;
+ }
+ }
+
+ //
+ // Build a HOB with the location of the reserved memory range.
+ //
+ CopyMem(&DescriptorAcpiVariable, &SmramHobDescriptorBlock->Descriptor[SmramRanges-1], sizeof(EFI_SMRAM_DESCRIPTOR));
+ DescriptorAcpiVariable.CpuStart += RESERVED_CPU_S3_SAVE_OFFSET;
+ BuildGuidDataHob (
+ &gEfiAcpiVariableGuid,
+ &DescriptorAcpiVariable,
+ sizeof (EFI_SMRAM_DESCRIPTOR)
+ );
+
+ //
+ // Get the location and size of the S3 memory range in the reserved page and
+ // install it as PEI Memory.
+ //
+
+ DEBUG ((EFI_D_INFO, "TSEG Base = 0x%08x\n", SmramHobDescriptorBlock->Descriptor[SmramRanges-1].PhysicalStart));
+ S3MemoryRangeData = (RESERVED_ACPI_S3_RANGE*)(UINTN)
+ (SmramHobDescriptorBlock->Descriptor[SmramRanges-1].PhysicalStart + RESERVED_ACPI_S3_RANGE_OFFSET);
+
+ S3MemoryBase = (UINTN) (S3MemoryRangeData->AcpiReservedMemoryBase);
+ DEBUG ((EFI_D_INFO, "S3MemoryBase = 0x%08x\n", S3MemoryBase));
+ S3MemorySize = (UINTN) (S3MemoryRangeData->AcpiReservedMemorySize);
+ DEBUG ((EFI_D_INFO, "S3MemorySize = 0x%08x\n", S3MemorySize));
+
+ Status = PeiServicesInstallPeiMemory (S3MemoryBase, S3MemorySize);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Retrieve the system memory length and build memory hob for the system
+ // memory above 1MB. So Memory Callback can set cache for the system memory
+ // correctly on S3 boot path, just like it does on Normal boot path.
+ //
+ ASSERT_EFI_ERROR ((S3MemoryRangeData->SystemMemoryLength - 0x100000) > 0);
+ BuildResourceDescriptorHob (
+ EFI_RESOURCE_SYSTEM_MEMORY,
+ (
+ EFI_RESOURCE_ATTRIBUTE_PRESENT |
+ EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+ EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
+ EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
+ EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
+ EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
+ ),
+ 0x100000,
+ S3MemoryRangeData->SystemMemoryLength - 0x100000
+ );
+
+ for (Index = 0; Index < NumRanges; Index++) {
+ if ((MemoryMap[Index].Type == DualChannelDdrMainMemory) &&
+ (MemoryMap[Index].PhysicalAddress + MemoryMap[Index].RangeLength < 0x100000)) {
+ BuildResourceDescriptorHob (
+ EFI_RESOURCE_SYSTEM_MEMORY,
+ (
+ EFI_RESOURCE_ATTRIBUTE_PRESENT |
+ EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+ EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
+ EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
+ EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
+ EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
+ ),
+ MemoryMap[Index].PhysicalAddress,
+ MemoryMap[Index].RangeLength
+ );
+ DEBUG ((EFI_D_INFO, "Build resource HOB for Legacy Region on S3 patch :"));
+ DEBUG ((EFI_D_INFO, " Memory Base:0x%lX Length:0x%lX\n", MemoryMap[Index].PhysicalAddress, MemoryMap[Index].RangeLength));
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+
+ This function returns the size, in bytes, required for the DXE phase.
+
+ @param PeiServices PEI Services table.
+ @param Size Pointer to the size, in bytes, required for the DXE phase.
+
+ @return None
+
+**/
+VOID
+RetriveRequiredMemorySize (
+ IN EFI_PEI_SERVICES **PeiServices,
+ OUT UINTN *Size
+ )
+{
+ EFI_STATUS Status;
+ EFI_PEI_HOB_POINTERS Hob;
+ EFI_MEMORY_TYPE_INFORMATION *MemoryData;
+ UINT8 Index;
+ UINTN TempPageNum;
+
+ MemoryData = NULL;
+ TempPageNum = 0;
+ Index = 0;
+
+ Status = PeiServicesGetHobList ((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);
+ }
+ //
+ // Platform PEIM should supply such a information. Generic PEIM doesn't assume any default value
+ //
+ if (!MemoryData) {
+ return ;
+ }
+
+ while (MemoryData[Index].Type != EfiMaxMemoryType) {
+ //
+ // Accumulate default memory size requirements
+ //
+ TempPageNum += MemoryData[Index].NumberOfPages;
+ Index++;
+ }
+
+ if (TempPageNum == 0) {
+ return ;
+ }
+
+ //
+ // Add additional pages used by DXE memory manager
+ //
+ (*Size) = (TempPageNum + EDKII_DXE_MEM_SIZE_PAGES) * EFI_PAGE_SIZE;
+
+ return ;
+}
+
+/**
+
+ This function returns the memory ranges to be enabled, along with information
+ describing how the range should be used.
+
+ @param PeiServices PEI Services Table.
+ @param TimingData Detected DDR timing parameters for installed memory.
+ @param RowConfArray Pointer to an array of EFI_DUAL_CHANNEL_DDR_ROW_CONFIG structures. The number
+ of items in the array must match MaxRows returned by the McGetRowInfo() function.
+ @param MemoryMap Buffer to record details of the memory ranges tobe enabled.
+ @param NumRanges On input, this contains the maximum number of memory ranges that can be described
+ in the MemoryMap buffer.
+
+ @return MemoryMap The buffer will be filled in
+ NumRanges will contain the actual number of memory ranges that are to be anabled.
+ EFI_SUCCESS The function completed successfully.
+
+**/
+EFI_STATUS
+GetMemoryMap (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINT32 TotalMemorySize,
+ IN OUT PEI_DUAL_CHANNEL_DDR_MEMORY_MAP_RANGE *MemoryMap,
+ IN OUT UINT8 *NumRanges
+ )
+{
+ EFI_PHYSICAL_ADDRESS MemorySize;
+ EFI_PHYSICAL_ADDRESS RowLength;
+ EFI_STATUS Status;
+ PEI_MEMORY_RANGE_PCI_MEMORY PciMemoryMask;
+ PEI_MEMORY_RANGE_OPTION_ROM OptionRomMask;
+ PEI_MEMORY_RANGE_SMRAM SmramMask;
+ PEI_MEMORY_RANGE_SMRAM TsegMask;
+ UINT32 BlockNum;
+ UINT8 EsmramcRegister;
+ UINT8 ExtendedMemoryIndex;
+ UINT32 Register;
+
+ if ((*NumRanges) < MAX_RANGES) {
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ *NumRanges = 0;
+
+ //
+ // Find out which memory ranges to reserve on this platform
+ //
+ Status = ChooseRanges (
+ &OptionRomMask,
+ &SmramMask,
+ &PciMemoryMask
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Generate Memory ranges for the memory map.
+ //
+ EsmramcRegister = 0;
+ MemorySize = 0;
+
+ RowLength = TotalMemorySize;
+
+ //
+ // Add memory below 640KB to the memory map. Make sure memory between
+ // 640KB and 1MB are reserved, even if not used for SMRAM
+ //
+ MemoryMap[*NumRanges].PhysicalAddress = MemorySize;
+ MemoryMap[*NumRanges].CpuAddress = MemorySize;
+ MemoryMap[*NumRanges].RangeLength = 0xA0000;
+ MemoryMap[*NumRanges].Type = DualChannelDdrMainMemory;
+ (*NumRanges)++;
+
+ //
+ // Just mark this range reserved
+ //
+ MemoryMap[*NumRanges].PhysicalAddress = 0xA0000;
+ MemoryMap[*NumRanges].CpuAddress = 0xA0000;
+ MemoryMap[*NumRanges].RangeLength = 0x60000;
+ MemoryMap[*NumRanges].Type = DualChannelDdrReservedMemory;
+ (*NumRanges)++;
+
+ RowLength -= (0x100000 - MemorySize);
+ MemorySize = 0x100000;
+
+ //
+ // Add remaining memory to the memory map
+ //
+ MemoryMap[*NumRanges].PhysicalAddress = MemorySize;
+ MemoryMap[*NumRanges].CpuAddress = MemorySize;
+ MemoryMap[*NumRanges].RangeLength = RowLength;
+ MemoryMap[*NumRanges].Type = DualChannelDdrMainMemory;
+ (*NumRanges)++;
+ MemorySize += RowLength;
+
+ ExtendedMemoryIndex = (UINT8) (*NumRanges - 1);
+
+ // See if we need to trim TSEG out of the highest memory range
+ //
+ if (SmramMask & PEI_MR_SMRAM_TSEG_MASK) {//pcd
+ //
+ // Create the new range for TSEG and remove that range from the previous SdrDdrMainMemory range
+ //
+ TsegMask = (SmramMask & PEI_MR_SMRAM_SIZE_MASK);
+
+ BlockNum = 1;
+ while (TsegMask) {
+ TsegMask >>= 1;
+ BlockNum <<= 1;
+ }
+
+ BlockNum >>= 1;
+
+ if (BlockNum) {
+
+ MemoryMap[*NumRanges].RangeLength = (BlockNum * 128 * 1024);
+ Register = (UINT32)((MemorySize - 1) & SMM_END_MASK);
+ MemorySize -= MemoryMap[*NumRanges].RangeLength;
+ MemoryMap[*NumRanges].PhysicalAddress = MemorySize;
+ MemoryMap[*NumRanges].CpuAddress = MemorySize;
+ MemoryMap[ExtendedMemoryIndex].RangeLength -= MemoryMap[*NumRanges].RangeLength;
+
+ //
+ // Update QuarkNcSoc HSMMCTL register
+ //
+ Register |= (UINT32)(((RShiftU64(MemorySize, 16)) & SMM_START_MASK) + (SMM_WRITE_OPEN | SMM_READ_OPEN | SMM_CODE_RD_OPEN));
+ QncHsmmcWrite (Register);
+ }
+
+ //
+ // Chipset only supports cacheable SMRAM
+ //
+ MemoryMap[*NumRanges].Type = DualChannelDdrSmramCacheable;
+
+ (*NumRanges)++;
+ }
+
+ //
+ // trim 64K memory from highest memory range for Rmu Main binary shadow
+ //
+ MemoryMap[*NumRanges].RangeLength = 0x10000;
+ MemorySize -= MemoryMap[*NumRanges].RangeLength;
+ MemoryMap[*NumRanges].PhysicalAddress = MemorySize;
+ MemoryMap[*NumRanges].CpuAddress = MemorySize;
+ MemoryMap[ExtendedMemoryIndex].RangeLength -= MemoryMap[*NumRanges].RangeLength;
+ MemoryMap[*NumRanges].Type = DualChannelDdrReservedMemory;
+ (*NumRanges)++;
+
+ return EFI_SUCCESS;
+}
+
+/**
+
+Routine Description:
+
+ Fill in bit masks to specify reserved memory ranges on the Lakeport platform
+
+Arguments:
+
+Returns:
+
+ OptionRomMask - Bit mask specifying memory regions reserved for Legacy option
+ ROM use (if any)
+
+ SmramMask - Bit mask specifying memory regions reserved for SMM use (if any)
+
+**/
+EFI_STATUS
+ChooseRanges (
+ IN OUT PEI_MEMORY_RANGE_OPTION_ROM *OptionRomMask,
+ IN OUT PEI_MEMORY_RANGE_SMRAM *SmramMask,
+ IN OUT PEI_MEMORY_RANGE_PCI_MEMORY *PciMemoryMask
+ )
+{
+
+ //
+ // Choose regions to reserve for Option ROM use
+ //
+ *OptionRomMask = PEI_MR_OPTION_ROM_NONE;
+
+ //
+ // Choose regions to reserve for SMM use (AB/H SEG and TSEG). Size is in 128K blocks
+ //
+ *SmramMask = PEI_MR_SMRAM_CACHEABLE_MASK | PEI_MR_SMRAM_TSEG_MASK | ((PcdGet32(PcdTSegSize)) >> 17);
+
+ *PciMemoryMask = 0;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+GetPlatformMemorySize (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_BOOT_MODE BootMode,
+ IN OUT UINT64 *MemorySize
+ )
+{
+ EFI_STATUS Status;
+ EFI_PEI_READ_ONLY_VARIABLE2_PPI *Variable;
+ UINTN DataSize;
+ EFI_MEMORY_TYPE_INFORMATION MemoryData [EfiMaxMemoryType + 1];
+ UINTN Index;
+
+ DataSize = sizeof (MemoryData);
+
+ if (BootMode == BOOT_IN_RECOVERY_MODE) {
+
+ //
+ // // Treat recovery as if variable not found (eg 1st boot).
+ //
+ Status = EFI_NOT_FOUND;
+
+ } else {
+ Status = PeiServicesLocatePpi (
+ &gEfiPeiReadOnlyVariable2PpiGuid,
+ 0,
+ NULL,
+ (VOID **)&Variable
+ );
+
+ ASSERT_EFI_ERROR (Status);
+
+ DataSize = sizeof (MemoryData);
+ Status = Variable->GetVariable (
+ Variable,
+ EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME,
+ &gEfiMemoryTypeInformationGuid,
+ NULL,
+ &DataSize,
+ &MemoryData
+ );
+ }
+
+ //
+ // Accumulate maximum amount of memory needed
+ //
+ if (EFI_ERROR (Status)) {
+ //
+ // Start with minimum memory
+ //
+ *MemorySize = PEI_MIN_MEMORY_SIZE;
+
+ for (Index = 0; Index < sizeof(mDefaultQncMemoryTypeInformation) / sizeof (EFI_MEMORY_TYPE_INFORMATION); Index++) {
+ *MemorySize += mDefaultQncMemoryTypeInformation[Index].NumberOfPages * EFI_PAGE_SIZE;
+ }
+
+ //
+ // Build the GUID'd HOB for DXE
+ //
+ BuildGuidDataHob (
+ &gEfiMemoryTypeInformationGuid,
+ mDefaultQncMemoryTypeInformation,
+ sizeof(mDefaultQncMemoryTypeInformation)
+ );
+ } else {
+ //
+ // Start with at least PEI_MIN_MEMORY_SIZE pages of memory for the DXE Core and the DXE Stack
+ //
+
+ *MemorySize = PEI_MIN_MEMORY_SIZE;
+ for (Index = 0; Index < DataSize / sizeof (EFI_MEMORY_TYPE_INFORMATION); Index++) {
+ DEBUG ((EFI_D_INFO, "Index %d, Page: %d\n", Index, MemoryData[Index].NumberOfPages));
+ *MemorySize += MemoryData[Index].NumberOfPages * EFI_PAGE_SIZE;
+ }
+
+ //
+ // Build the GUID'd HOB for DXE
+ //
+ BuildGuidDataHob (
+ &gEfiMemoryTypeInformationGuid,
+ MemoryData,
+ DataSize
+ );
+
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+BaseMemoryTest (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PHYSICAL_ADDRESS BeginAddress,
+ IN UINT64 MemoryLength,
+ IN PEI_MEMORY_TEST_OP Operation,
+ OUT EFI_PHYSICAL_ADDRESS *ErrorAddress
+ )
+{
+ UINT32 TestPattern;
+ EFI_PHYSICAL_ADDRESS TempAddress;
+ UINT32 SpanSize;
+
+ TestPattern = 0x5A5A5A5A;
+ SpanSize = 0;
+
+ //
+ // Make sure we don't try and test anything above the max physical address range
+ //
+ ASSERT (BeginAddress + MemoryLength < MAX_ADDRESS);
+
+ switch (Operation) {
+ case Extensive:
+ SpanSize = 0x4;
+ break;
+
+ case Sparse:
+ case Quick:
+ SpanSize = 0x40000;
+ break;
+
+ case Ignore:
+ goto Done;
+ break;
+ }
+ //
+ // Write the test pattern into memory range
+ //
+ TempAddress = BeginAddress;
+ while (TempAddress < BeginAddress + MemoryLength) {
+ (*(UINT32 *) (UINTN) TempAddress) = TestPattern;
+ TempAddress += SpanSize;
+ }
+ //
+ // Read pattern from memory and compare it
+ //
+ TempAddress = BeginAddress;
+ while (TempAddress < BeginAddress + MemoryLength) {
+ if ((*(UINT32 *) (UINTN) TempAddress) != TestPattern) {
+ *ErrorAddress = TempAddress;
+ DEBUG ((EFI_D_ERROR, "Memory test failed at 0x%x.\n", TempAddress));
+ return EFI_DEVICE_ERROR;
+ }
+
+ TempAddress += SpanSize;
+ }
+
+Done:
+ return EFI_SUCCESS;
+}
+
+/**
+
+ This function sets up the platform specific IMR protection for the various
+ memory regions.
+
+ @param PeiMemoryBaseAddress Base address of memory allocated for PEI.
+ @param PeiMemoryLength Length in bytes of the PEI memory (includes ACPI memory).
+ @param RequiredMemSize Size in bytes of the ACPI/Runtime memory
+
+ @return EFI_SUCCESS The function completed successfully.
+ EFI_ACCESS_DENIED Access to IMRs failed.
+
+**/
+EFI_STATUS
+SetPlatformImrPolicy (
+ IN EFI_PHYSICAL_ADDRESS PeiMemoryBaseAddress,
+ IN UINT64 PeiMemoryLength,
+ IN UINTN RequiredMemSize
+ )
+{
+ UINT8 Index;
+ UINT32 Register;
+ UINT16 DeviceId;
+
+ //
+ // Check what Soc we are running on (read Host bridge DeviceId)
+ //
+ DeviceId = QNCMmPci16(0, MC_BUS, MC_DEV, MC_FUN, PCI_DEVICE_ID_OFFSET);
+
+ //
+ // If any IMR register is locked then we cannot proceed
+ //
+ for (Index = (QUARK_NC_MEMORY_MANAGER_IMR0+QUARK_NC_MEMORY_MANAGER_IMRXL); Index <=(QUARK_NC_MEMORY_MANAGER_IMR7+QUARK_NC_MEMORY_MANAGER_IMRXL); Index=Index+4)
+ {
+ Register = QNCPortRead (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, Index);
+ if (Register & IMR_LOCK) {
+ return EFI_ACCESS_DENIED;
+ }
+ }
+
+ //
+ // Add IMR0 protection for the 'PeiMemory'
+ //
+ QncImrWrite (
+ QUARK_NC_MEMORY_MANAGER_IMR0,
+ (UINT32)(((RShiftU64(PeiMemoryBaseAddress, 8)) & IMRL_MASK) | IMR_EN),
+ (UINT32)((RShiftU64((PeiMemoryBaseAddress+PeiMemoryLength-RequiredMemSize + EFI_PAGES_TO_SIZE(EDKII_DXE_MEM_SIZE_PAGES-1) - 1), 8)) & IMRL_MASK),
+ (UINT32)(CPU_SNOOP + CPU0_NON_SMM),
+ (UINT32)(CPU_SNOOP + CPU0_NON_SMM)
+ );
+
+ //
+ // Add IMR2 protection for shadowed RMU binary.
+ //
+ QncImrWrite (
+ QUARK_NC_MEMORY_MANAGER_IMR2,
+ (UINT32)(((RShiftU64((PeiMemoryBaseAddress+PeiMemoryLength), 8)) & IMRH_MASK) | IMR_EN),
+ (UINT32)((RShiftU64((PeiMemoryBaseAddress+PeiMemoryLength+PcdGet32(PcdFlashQNCMicrocodeSize)-1), 8)) & IMRH_MASK),
+ (UINT32)(CPU_SNOOP + RMU + CPU0_NON_SMM),
+ (UINT32)(CPU_SNOOP + RMU + CPU0_NON_SMM)
+ );
+
+ //
+ // Add IMR3 protection for the default SMRAM.
+ //
+ QncImrWrite (
+ QUARK_NC_MEMORY_MANAGER_IMR3,
+ (UINT32)(((RShiftU64((SMM_DEFAULT_SMBASE), 8)) & IMRL_MASK) | IMR_EN),
+ (UINT32)((RShiftU64((SMM_DEFAULT_SMBASE+SMM_DEFAULT_SMBASE_SIZE_BYTES-1), 8)) & IMRH_MASK),
+ (UINT32)(CPU_SNOOP + CPU0_NON_SMM),
+ (UINT32)(CPU_SNOOP + CPU0_NON_SMM)
+ );
+
+ //
+ // Add IMR5 protection for the legacy S3 and AP Startup Vector region (below 1MB).
+ //
+ QncImrWrite (
+ QUARK_NC_MEMORY_MANAGER_IMR5,
+ (UINT32)(((RShiftU64(AP_STARTUP_VECTOR, 8)) & IMRL_MASK) | IMR_EN),
+ (UINT32)((RShiftU64((AP_STARTUP_VECTOR + EFI_PAGE_SIZE - 1), 8)) & IMRH_MASK),
+ (UINT32)(CPU_SNOOP + CPU0_NON_SMM),
+ (UINT32)(CPU_SNOOP + CPU0_NON_SMM)
+ );
+
+ //
+ // Add IMR6 protection for the ACPI Reclaim/ACPI/Runtime Services.
+ //
+ QncImrWrite (
+ QUARK_NC_MEMORY_MANAGER_IMR6,
+ (UINT32)(((RShiftU64((PeiMemoryBaseAddress+PeiMemoryLength-RequiredMemSize+EFI_PAGES_TO_SIZE(EDKII_DXE_MEM_SIZE_PAGES-1)), 8)) & IMRL_MASK) | IMR_EN),
+ (UINT32)((RShiftU64((PeiMemoryBaseAddress+PeiMemoryLength-EFI_PAGE_SIZE-1), 8)) & IMRH_MASK),
+ (UINT32)(CPU_SNOOP + CPU0_NON_SMM),
+ (UINT32)(CPU_SNOOP + CPU0_NON_SMM)
+ );
+
+ //
+ // Enable IMR4 protection of eSRAM.
+ //
+ QncImrWrite (
+ QUARK_NC_MEMORY_MANAGER_IMR4,
+ (UINT32)(((RShiftU64((UINTN)PcdGet32 (PcdEsramStage1Base), 8)) & IMRL_MASK) | IMR_EN),
+ (UINT32)((RShiftU64(((UINTN)PcdGet32 (PcdEsramStage1Base) + (UINTN)PcdGet32 (PcdESramMemorySize) - 1), 8)) & IMRH_MASK),
+ (UINT32)(CPU_SNOOP + CPU0_NON_SMM),
+ (UINT32)(CPU_SNOOP + CPU0_NON_SMM)
+ );
+
+ //
+ // Enable Interrupt on IMR/SMM Violation
+ //
+ QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_BIMRVCTL, (UINT32)(EnableIMRInt));
+ if (DeviceId == QUARK2_MC_DEVICE_ID) {
+ QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_BSMMVCTL, (UINT32)(EnableSMMInt));
+ }
+
+ //
+ // Disable IMR7 memory protection (eSRAM + DDR3 memory) since our policies
+ // are now setup.
+ //
+ QncImrWrite (
+ QUARK_NC_MEMORY_MANAGER_IMR7,
+ (UINT32)(IMRL_RESET & ~IMR_EN),
+ (UINT32)IMRH_RESET,
+ (UINT32)IMRX_ALL_ACCESS,
+ (UINT32)IMRX_ALL_ACCESS
+ );
+
+ return EFI_SUCCESS;
+}
+
+/** Return info derived from Installing Memory by MemoryInit.
+
+ @param[out] RmuMainBaseAddressPtr Return RmuMainBaseAddress to this location.
+ @param[out] SmramDescriptorPtr Return start of Smram descriptor list to this location.
+ @param[out] NumSmramRegionsPtr Return numbers of Smram regions to this location.
+
+ @return Address of RMU shadow region at the top of available memory.
+ @return List of Smram descriptors for each Smram region.
+ @return Numbers of Smram regions.
+**/
+VOID
+EFIAPI
+InfoPostInstallMemory (
+ OUT UINT32 *RmuMainBaseAddressPtr OPTIONAL,
+ OUT EFI_SMRAM_DESCRIPTOR **SmramDescriptorPtr OPTIONAL,
+ OUT UINTN *NumSmramRegionsPtr OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ EFI_PEI_HOB_POINTERS Hob;
+ UINT64 CalcLength;
+ EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *SmramHobDescriptorBlock;
+
+ if ((RmuMainBaseAddressPtr == NULL) && (SmramDescriptorPtr == NULL) && (NumSmramRegionsPtr == NULL)) {
+ return;
+ }
+
+ SmramHobDescriptorBlock = NULL;
+ if (SmramDescriptorPtr != NULL) {
+ *SmramDescriptorPtr = NULL;
+ }
+ if (NumSmramRegionsPtr != NULL) {
+ *NumSmramRegionsPtr = 0;
+ }
+
+ //
+ // Calculate RMU shadow region base address.
+ // Set to 1 MB. Since 1MB cacheability will always be set
+ // until override by CSM.
+ //
+ CalcLength = 0x100000;
+
+ Status = PeiServicesGetHobList ((VOID **) &Hob.Raw);
+ ASSERT_EFI_ERROR (Status);
+ while (!END_OF_HOB_LIST (Hob)) {
+ if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
+ if (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) {
+ //
+ // Skip the memory region below 1MB
+ //
+ if (Hob.ResourceDescriptor->PhysicalStart >= 0x100000) {
+ CalcLength += (UINT64) (Hob.ResourceDescriptor->ResourceLength);
+ }
+ }
+ } else if (Hob.Header->HobType == EFI_HOB_TYPE_GUID_EXTENSION) {
+ if (CompareGuid (&(Hob.Guid->Name), &gEfiSmmPeiSmramMemoryReserveGuid)) {
+ SmramHobDescriptorBlock = (VOID*) (Hob.Raw + sizeof (EFI_HOB_GUID_TYPE));
+ if (SmramDescriptorPtr != NULL) {
+ *SmramDescriptorPtr = SmramHobDescriptorBlock->Descriptor;
+ }
+ if (NumSmramRegionsPtr != NULL) {
+ *NumSmramRegionsPtr = SmramHobDescriptorBlock->NumberOfSmmReservedRegions;
+ }
+ }
+ }
+ Hob.Raw = GET_NEXT_HOB (Hob);
+ }
+
+ if (RmuMainBaseAddressPtr != NULL) {
+ *RmuMainBaseAddressPtr = (UINT32) CalcLength;
+ }
+}
diff --git a/QuarkPlatformPkg/Platform/Pei/PlatformInit/MrcWrapper.h b/QuarkPlatformPkg/Platform/Pei/PlatformInit/MrcWrapper.h
new file mode 100644
index 0000000000..e0f06a3b0e
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Pei/PlatformInit/MrcWrapper.h
@@ -0,0 +1,240 @@
+/** @file
+Framework PEIM to initialize memory on an DDR2 SDRAM Memory Controller.
+
+Copyright (c) 2013 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _MRC_WRAPPER_H
+#define _MRC_WRAPPER_H
+
+#include <Ppi/QNCMemoryInit.h>
+#include "PlatformEarlyInit.h"
+
+//
+// Define the default memory areas required
+//
+#define EDKII_RESERVED_SIZE_PAGES 0x40
+#define ACPI_NVS_SIZE_PAGES 0x40
+#define RUNTIME_SERVICES_DATA_SIZE_PAGES 0x20
+#define RUNTIME_SERVICES_CODE_SIZE_PAGES 0x60
+#define ACPI_RECLAIM_SIZE_PAGES 0x10
+#define EDKII_DXE_MEM_SIZE_PAGES 0x20
+
+#define AP_STARTUP_VECTOR 0x00097000
+
+//
+// Maximum number of "Socket Sets", where a "Socket Set is a set of matching
+// DIMM's from the various channels
+//
+#define MAX_SOCKET_SETS 2
+
+//
+// Maximum number of memory ranges supported by the memory controller
+//
+#define MAX_RANGES (MAX_ROWS + 5)
+
+//
+// Min. of 48MB PEI phase
+//
+#define PEI_MIN_MEMORY_SIZE (6 * 0x800000)
+#define PEI_RECOVERY_MIN_MEMORY_SIZE (6 * 0x800000)
+
+#define PEI_MEMORY_RANGE_OPTION_ROM UINT32
+#define PEI_MR_OPTION_ROM_NONE 0x00000000
+
+//
+// SMRAM Memory Range
+//
+#define PEI_MEMORY_RANGE_SMRAM UINT32
+#define PEI_MR_SMRAM_ALL 0xFFFFFFFF
+#define PEI_MR_SMRAM_NONE 0x00000000
+#define PEI_MR_SMRAM_CACHEABLE_MASK 0x80000000
+#define PEI_MR_SMRAM_SEGTYPE_MASK 0x00FF0000
+#define PEI_MR_SMRAM_ABSEG_MASK 0x00010000
+#define PEI_MR_SMRAM_HSEG_MASK 0x00020000
+#define PEI_MR_SMRAM_TSEG_MASK 0x00040000
+//
+// SMRAM Size is a multiple of 128KB.
+//
+#define PEI_MR_SMRAM_SIZE_MASK 0x0000FFFF
+
+//
+// Pci Memory Hole
+//
+#define PEI_MEMORY_RANGE_PCI_MEMORY UINT32
+
+typedef enum {
+ Ignore,
+ Quick,
+ Sparse,
+ Extensive
+} PEI_MEMORY_TEST_OP;
+
+//
+// MRC Params Variable structure.
+//
+
+typedef struct {
+ MrcTimings_t timings; // Actual MRC config values saved in variable store.
+ UINT8 VariableStorePad[8]; // Allow for data stored in variable is required to be multiple of 8bytes.
+} PLATFORM_VARIABLE_MEMORY_CONFIG_DATA;
+
+///
+/// MRC Params Platform Data Flags bits
+///
+#define PDAT_MRC_FLAG_ECC_EN BIT0
+#define PDAT_MRC_FLAG_SCRAMBLE_EN BIT1
+#define PDAT_MRC_FLAG_MEMTEST_EN BIT2
+#define PDAT_MRC_FLAG_TOP_TREE_EN BIT3 ///< 0b DDR "fly-by" topology else 1b DDR "tree" topology.
+#define PDAT_MRC_FLAG_WR_ODT_EN BIT4 ///< If set ODR signal is asserted to DRAM devices on writes.
+
+///
+/// MRC Params Platform Data.
+///
+typedef struct {
+ UINT32 Flags; ///< Bitmap of PDAT_MRC_FLAG_XXX defs above.
+ UINT8 DramWidth; ///< 0=x8, 1=x16, others=RESERVED.
+ UINT8 DramSpeed; ///< 0=DDRFREQ_800, 1=DDRFREQ_1066, others=RESERVED. Only 533MHz SKU support 1066 memory.
+ UINT8 DramType; ///< 0=DDR3,1=DDR3L, others=RESERVED.
+ UINT8 RankMask; ///< bit[0] RANK0_EN, bit[1] RANK1_EN, others=RESERVED.
+ UINT8 ChanMask; ///< bit[0] CHAN0_EN, others=RESERVED.
+ UINT8 ChanWidth; ///< 1=x16, others=RESERVED.
+ UINT8 AddrMode; ///< 0, 1, 2 (mode 2 forced if ecc enabled), others=RESERVED.
+ UINT8 SrInt; ///< 1=1.95us, 2=3.9us, 3=7.8us, others=RESERVED. REFRESH_RATE.
+ UINT8 SrTemp; ///< 0=normal, 1=extended, others=RESERVED.
+ UINT8 DramRonVal; ///< 0=34ohm, 1=40ohm, others=RESERVED. RON_VALUE Select MRS1.DIC driver impedance control.
+ UINT8 DramRttNomVal; ///< 0=40ohm, 1=60ohm, 2=120ohm, others=RESERVED.
+ UINT8 DramRttWrVal; ///< 0=off others=RESERVED.
+ UINT8 SocRdOdtVal; ///< 0=off, 1=60ohm, 2=120ohm, 3=180ohm, others=RESERVED.
+ UINT8 SocWrRonVal; ///< 0=27ohm, 1=32ohm, 2=40ohm, others=RESERVED.
+ UINT8 SocWrSlewRate; ///< 0=2.5V/ns, 1=4V/ns, others=RESERVED.
+ UINT8 DramDensity; ///< 0=512Mb, 1=1Gb, 2=2Gb, 3=4Gb, others=RESERVED.
+ UINT32 tRAS; ///< ACT to PRE command period in picoseconds.
+ UINT32 tWTR; ///< Delay from start of internal write transaction to internal read command in picoseconds.
+ UINT32 tRRD; ///< ACT to ACT command period (JESD79 specific to page size 1K/2K) in picoseconds.
+ UINT32 tFAW; ///< Four activate window (JESD79 specific to page size 1K/2K) in picoseconds.
+ UINT8 tCL; ///< DRAM CAS Latency in clocks.
+} PDAT_MRC_ITEM;
+
+//
+// Memory range types
+//
+typedef enum {
+ DualChannelDdrMainMemory,
+ DualChannelDdrSmramCacheable,
+ DualChannelDdrSmramNonCacheable,
+ DualChannelDdrGraphicsMemoryCacheable,
+ DualChannelDdrGraphicsMemoryNonCacheable,
+ DualChannelDdrReservedMemory,
+ DualChannelDdrMaxMemoryRangeType
+} PEI_DUAL_CHANNEL_DDR_MEMORY_RANGE_TYPE;
+
+//
+// Memory map range information
+//
+typedef struct {
+ EFI_PHYSICAL_ADDRESS PhysicalAddress;
+ EFI_PHYSICAL_ADDRESS CpuAddress;
+ EFI_PHYSICAL_ADDRESS RangeLength;
+ PEI_DUAL_CHANNEL_DDR_MEMORY_RANGE_TYPE Type;
+} PEI_DUAL_CHANNEL_DDR_MEMORY_MAP_RANGE;
+
+//
+// Function prototypes.
+//
+
+EFI_STATUS
+InstallEfiMemory (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariableServices,
+ IN EFI_BOOT_MODE BootMode,
+ IN UINT32 TotalMemorySize
+ );
+
+EFI_STATUS
+InstallS3Memory (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariableServices,
+ IN UINT32 TotalMemorySize
+ );
+
+EFI_STATUS
+MemoryInit (
+ IN EFI_PEI_SERVICES **PeiServices
+ );
+
+
+EFI_STATUS
+LoadConfig (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariableServices,
+ IN OUT MRCParams_t *MrcData
+ );
+
+EFI_STATUS
+SaveConfig (
+ IN MRCParams_t *MrcData
+ );
+
+VOID
+RetriveRequiredMemorySize (
+ IN EFI_PEI_SERVICES **PeiServices,
+ OUT UINTN *Size
+ );
+
+EFI_STATUS
+GetMemoryMap (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINT32 TotalMemorySize,
+ IN OUT PEI_DUAL_CHANNEL_DDR_MEMORY_MAP_RANGE *MemoryMap,
+ IN OUT UINT8 *NumRanges
+ );
+
+EFI_STATUS
+ChooseRanges (
+ IN OUT PEI_MEMORY_RANGE_OPTION_ROM *OptionRomMask,
+ IN OUT PEI_MEMORY_RANGE_SMRAM *SmramMask,
+ IN OUT PEI_MEMORY_RANGE_PCI_MEMORY *PciMemoryMask
+ );
+
+EFI_STATUS
+GetPlatformMemorySize (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_BOOT_MODE BootMode,
+ IN OUT UINT64 *MemorySize
+ );
+
+EFI_STATUS
+BaseMemoryTest (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PHYSICAL_ADDRESS BeginAddress,
+ IN UINT64 MemoryLength,
+ IN PEI_MEMORY_TEST_OP Operation,
+ OUT EFI_PHYSICAL_ADDRESS *ErrorAddress
+ );
+
+EFI_STATUS
+SetPlatformImrPolicy (
+ IN EFI_PHYSICAL_ADDRESS PeiMemoryBaseAddress,
+ IN UINT64 PeiMemoryLength,
+ IN UINTN RequiredMemSize
+ );
+
+VOID
+EFIAPI
+InfoPostInstallMemory (
+ OUT UINT32 *RmuBaseAddressPtr OPTIONAL,
+ OUT EFI_SMRAM_DESCRIPTOR **SmramDescriptorPtr OPTIONAL,
+ OUT UINTN *NumSmramRegionsPtr OPTIONAL
+ );
+
+#endif
diff --git a/QuarkPlatformPkg/Platform/Pei/PlatformInit/PeiFvSecurity.c b/QuarkPlatformPkg/Platform/Pei/PlatformInit/PeiFvSecurity.c
new file mode 100644
index 0000000000..d0246be2e0
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Pei/PlatformInit/PeiFvSecurity.c
@@ -0,0 +1,117 @@
+/** @file
+EFI PEI Platform Security services
+
+Copyright (c) 2013 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "PeiFvSecurity.h"
+
+EFI_PEI_NOTIFY_DESCRIPTOR mNotifyOnFvInfoSecurityList = {
+ (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiPeiFirmwareVolumeInfoPpiGuid,
+ FirmwareVolmeInfoPpiNotifySecurityCallback
+};
+
+/**
+ Callback function to perform FV security checking on a FV Info PPI.
+
+ @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
+ @param NotifyDescriptor Address of the notification descriptor data structure.
+ @param Ppi Address of the PPI that was installed.
+
+ @retval EFI_SUCCESS
+
+**/
+EFI_STATUS
+EFIAPI
+FirmwareVolmeInfoPpiNotifySecurityCallback (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ )
+{
+ EFI_STATUS Status;
+ EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *FvInfoPpi;
+ EFI_PEI_FIRMWARE_VOLUME_PPI *FvPpi;
+
+ FvInfoPpi = (EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *)Ppi;
+
+ //
+ // Locate the corresponding FV_PPI according to founded FV's format guid
+ //
+ Status = PeiServicesLocatePpi (
+ &FvInfoPpi->FvFormat,
+ 0,
+ NULL,
+ (VOID**)&FvPpi
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Only authenticate parent Firmware Volume (child firmware volumes are covered by the parent)
+ //
+ if ((VOID *)FvInfoPpi->ParentFvName == NULL && (VOID *)FvInfoPpi->ParentFileName == NULL) {
+ Status = PeiSecurityVerifyFv ((EFI_FIRMWARE_VOLUME_HEADER*) FvInfoPpi->FvInfo);
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Authenticates the Firmware Volume
+
+ @param CurrentFvAddress Pointer to the current Firmware Volume under consideration
+
+ @retval EFI_SUCCESS Firmware Volume is legal
+
+**/
+EFI_STATUS
+PeiSecurityVerifyFv (
+ IN EFI_FIRMWARE_VOLUME_HEADER *CurrentFvAddress
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Call Security library to authenticate the Firmware Volume
+ //
+ DEBUG ((DEBUG_INFO, "PeiSecurityVerifyFv - CurrentFvAddress=0x%8x\n", (UINT32)CurrentFvAddress));
+ Status = EFI_SUCCESS;
+
+ return Status;
+}
+
+/**
+
+ Entry point for the PEI Security PEIM
+ Sets up a notification to perform PEI security checking
+
+ @param FfsHeader Not used.
+ @param PeiServices General purpose services available to every PEIM.
+
+ @return EFI_SUCCESS PEI Security notification installed successfully.
+ All others: PEI Security notification failed to install.
+
+**/
+EFI_STATUS
+PeiInitializeFvSecurity (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+
+ Status = PeiServicesNotifyPpi (&mNotifyOnFvInfoSecurityList);
+
+ return Status;
+}
+
diff --git a/QuarkPlatformPkg/Platform/Pei/PlatformInit/PeiFvSecurity.h b/QuarkPlatformPkg/Platform/Pei/PlatformInit/PeiFvSecurity.h
new file mode 100644
index 0000000000..f55b6b8856
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Pei/PlatformInit/PeiFvSecurity.h
@@ -0,0 +1,73 @@
+/** @file
+Definition of Pei Core Structures and Services
+
+Copyright (c) 2013 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _PEI_FV_SECURITY_H_
+#define _PEI_FV_SECURITY_H_
+
+#include <Ppi/FirmwareVolume.h>
+#include <Ppi/FirmwareVolumeInfo.h>
+#include <Library/DebugLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+/**
+ Callback function to perform FV security checking on a FV Info PPI.
+
+ @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
+ @param NotifyDescriptor Address of the notification descriptor data structure.
+ @param Ppi Address of the PPI that was installed.
+
+ @retval EFI_SUCCESS
+
+**/
+EFI_STATUS
+EFIAPI
+FirmwareVolmeInfoPpiNotifySecurityCallback (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ );
+
+/**
+ Authenticates the Firmware Volume
+
+ @param CurrentFvAddress Pointer to the current Firmware Volume under consideration
+
+ @retval EFI_SUCCESS Firmware Volume is legal
+
+**/
+EFI_STATUS
+PeiSecurityVerifyFv (
+ IN EFI_FIRMWARE_VOLUME_HEADER *CurrentFvAddress
+ );
+
+/**
+
+ Entry point for the PEI Security PEIM
+ Sets up a notification to perform PEI security checking
+
+ @param FfsHeader Not used.
+ @param PeiServices General purpose services available to every PEIM.
+
+ @return EFI_SUCCESS PEI Security notification installed successfully.
+ All others: PEI Security notification failed to install.
+
+**/
+EFI_STATUS
+PeiInitializeFvSecurity (
+ VOID
+ );
+
+#endif
diff --git a/QuarkPlatformPkg/Platform/Pei/PlatformInit/PlatformEarlyInit.c b/QuarkPlatformPkg/Platform/Pei/PlatformInit/PlatformEarlyInit.c
new file mode 100644
index 0000000000..32ae3e0891
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Pei/PlatformInit/PlatformEarlyInit.c
@@ -0,0 +1,962 @@
+/** @file
+This PEIM initialize platform for MRC, following action is performed,
+1. Initizluize GMCH
+2. Detect boot mode
+3. Detect video adapter to determine whether we need pre allocated memory
+4. Calls MRC to initialize memory and install a PPI notify to do post memory initialization.
+This file contains the main entrypoint of the PEIM.
+
+Copyright (c) 2013 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+
+#include "CommonHeader.h"
+#include "PlatformEarlyInit.h"
+#include "PeiFvSecurity.h"
+
+EFI_STATUS
+EFIAPI
+EndOfPeiSignalPpiNotifyCallback (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ );
+
+//
+// Function prototypes to routines implemented in other source modules
+// within this component.
+//
+
+EFI_STATUS
+EFIAPI
+PlatformErratasPostMrc (
+ VOID
+ );
+
+//
+// The global indicator, the FvFileLoader callback will modify it to TRUE after loading PEIM into memory
+//
+BOOLEAN ImageInMemory = FALSE;
+
+BOARD_LEGACY_GPIO_CONFIG mBoardLegacyGpioConfigTable[] = { PLATFORM_LEGACY_GPIO_TABLE_DEFINITION };
+UINTN mBoardLegacyGpioConfigTableLen = (sizeof(mBoardLegacyGpioConfigTable) / sizeof(BOARD_LEGACY_GPIO_CONFIG));
+BOARD_GPIO_CONTROLLER_CONFIG mBoardGpioControllerConfigTable[] = { PLATFORM_GPIO_CONTROLLER_CONFIG_DEFINITION };
+UINTN mBoardGpioControllerConfigTableLen = (sizeof(mBoardGpioControllerConfigTable) / sizeof(BOARD_GPIO_CONTROLLER_CONFIG));
+UINT8 ChipsetDefaultMac [6] = {0xff,0xff,0xff,0xff,0xff,0xff};
+
+EFI_PEI_PPI_DESCRIPTOR mPpiBootMode[1] = {
+ {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiPeiMasterBootModePpiGuid,
+ NULL
+ }
+};
+
+EFI_PEI_NOTIFY_DESCRIPTOR mMemoryDiscoveredNotifyList[1] = {
+ {
+ (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiPeiMemoryDiscoveredPpiGuid,
+ MemoryDiscoveredPpiNotifyCallback
+ }
+};
+
+EFI_PEI_NOTIFY_DESCRIPTOR mEndOfPeiSignalPpiNotifyList[1] = {
+ {
+ (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiEndOfPeiSignalPpiGuid,
+ EndOfPeiSignalPpiNotifyCallback
+ }
+};
+
+EFI_PEI_STALL_PPI mStallPpi = {
+ PEI_STALL_RESOLUTION,
+ Stall
+};
+
+EFI_PEI_PPI_DESCRIPTOR mPpiStall[1] = {
+ {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiPeiStallPpiGuid,
+ &mStallPpi
+ }
+};
+
+/**
+ Set Mac address on chipset ethernet device.
+
+ @param Bus PCI Bus number of chipset ethernet device.
+ @param Device Device number of chipset ethernet device.
+ @param Func PCI Function number of chipset ethernet device.
+ @param MacAddr MAC Address to set.
+
+**/
+VOID
+EFIAPI
+SetLanControllerMacAddr (
+ IN CONST UINT8 Bus,
+ IN CONST UINT8 Device,
+ IN CONST UINT8 Func,
+ IN CONST UINT8 *MacAddr,
+ IN CONST UINT32 Bar0
+ )
+{
+ UINT32 Data32;
+ UINT16 PciVid;
+ UINT16 PciDid;
+ UINT32 Addr;
+ UINT32 MacVer;
+ volatile UINT8 *Wrote;
+ UINT32 DevPcieAddr;
+ UINT16 SaveCmdReg;
+ UINT32 SaveBarReg;
+
+ DevPcieAddr = PCI_LIB_ADDRESS (
+ Bus,
+ Device,
+ Func,
+ 0
+ );
+
+ //
+ // Do nothing if not a supported device.
+ //
+ PciVid = PciRead16 (DevPcieAddr + PCI_VENDOR_ID_OFFSET);
+ PciDid = PciRead16 (DevPcieAddr + PCI_DEVICE_ID_OFFSET);
+ if((PciVid != V_IOH_MAC_VENDOR_ID) || (PciDid != V_IOH_MAC_DEVICE_ID)) {
+ return;
+ }
+
+ //
+ // Save current settings for PCI CMD/BAR registers
+ //
+ SaveCmdReg = PciRead16 (DevPcieAddr + PCI_COMMAND_OFFSET);
+ SaveBarReg = PciRead32 (DevPcieAddr + R_IOH_MAC_MEMBAR);
+
+ //
+ // Use predefined tempory memory resource
+ //
+ PciWrite32 ( DevPcieAddr + R_IOH_MAC_MEMBAR, Bar0);
+ PciWrite8 ( DevPcieAddr + PCI_COMMAND_OFFSET, EFI_PCI_COMMAND_MEMORY_SPACE);
+
+ Addr = Bar0 + R_IOH_MAC_GMAC_REG_8;
+ MacVer = *((volatile UINT32 *) (UINTN)(Addr));
+
+ DEBUG ((EFI_D_INFO, "Ioh MAC [B:%d, D:%d, F:%d] VER:%04x ADDR:",
+ (UINTN) Bus,
+ (UINTN) Device,
+ (UINTN) Func,
+ (UINTN) MacVer
+ ));
+
+ //
+ // Set MAC Address0 Low Register (GMAC_REG_17) ADDRLO bits.
+ //
+ Addr = Bar0 + R_IOH_MAC_GMAC_REG_17;
+ Data32 = *((UINT32 *) (UINTN)(&MacAddr[0]));
+ *((volatile UINT32 *) (UINTN)(Addr)) = Data32;
+ Wrote = (volatile UINT8 *) (UINTN)(Addr);
+ DEBUG ((EFI_D_INFO, "%02x-%02x-%02x-%02x-",
+ (UINTN) Wrote[0],
+ (UINTN) Wrote[1],
+ (UINTN) Wrote[2],
+ (UINTN) Wrote[3]
+ ));
+
+ //
+ // Set MAC Address0 High Register (GMAC_REG_16) ADDRHI bits
+ // and Address Enable (AE) bit.
+ //
+ Addr = Bar0 + R_IOH_MAC_GMAC_REG_16;
+ Data32 =
+ ((UINT32) MacAddr[4]) |
+ (((UINT32)MacAddr[5]) << 8) |
+ B_IOH_MAC_AE;
+ *((volatile UINT32 *) (UINTN)(Addr)) = Data32;
+ Wrote = (volatile UINT8 *) (UINTN)(Addr);
+
+ DEBUG ((EFI_D_INFO, "%02x-%02x\n", (UINTN) Wrote[0], (UINTN) Wrote[1]));
+
+ //
+ // Restore settings for PCI CMD/BAR registers
+ //
+ PciWrite32 ((DevPcieAddr + R_IOH_MAC_MEMBAR), SaveBarReg);
+ PciWrite16 (DevPcieAddr + PCI_COMMAND_OFFSET, SaveCmdReg);
+}
+
+/**
+ This is the entrypoint of PEIM
+
+ @param FileHandle Handle of the file being invoked.
+ @param PeiServices Describes the list of possible PEI Services.
+
+ @retval EFI_SUCCESS if it completed successfully.
+**/
+EFI_STATUS
+EFIAPI
+PeiInitPlatform (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ EFI_STATUS Status;
+ EFI_BOOT_MODE BootMode;
+ EFI_PEI_STALL_PPI *StallPpi;
+ EFI_PEI_PPI_DESCRIPTOR *StallPeiPpiDescriptor;
+ EFI_FV_FILE_INFO FileInfo;
+ EFI_PLATFORM_TYPE PlatformType;
+
+ PlatformType = (EFI_PLATFORM_TYPE)PcdGet16 (PcdPlatformType);
+
+ //
+ // Initialize Firmware Volume security.
+ // This must be done before any firmware volume accesses (excl. BFV)
+ //
+ Status = PeiInitializeFvSecurity();
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Do any early platform specific initialization.
+ //
+ EarlyPlatformInit ();
+
+ //
+ // This is a second path on entry, in recovery boot path the Stall PPI need to be memory-based
+ // to improve recovery performance.
+ //
+ Status = PeiServicesFfsGetFileInfo (FileHandle, &FileInfo);
+ ASSERT_EFI_ERROR (Status);
+ //
+ // The follow conditional check only works for memory-mapped FFS,
+ // so we ASSERT that the file is really a MM FFS.
+ //
+ ASSERT (FileInfo.Buffer != NULL);
+ if (!(((UINTN) FileInfo.Buffer <= (UINTN) PeiInitPlatform) &&
+ ((UINTN) PeiInitPlatform <= (UINTN) FileInfo.Buffer + FileInfo.BufferSize))) {
+ //
+ // Now that module in memory, update the
+ // PPI that describes the Stall to other modules
+ //
+ Status = PeiServicesLocatePpi (
+ &gEfiPeiStallPpiGuid,
+ 0,
+ &StallPeiPpiDescriptor,
+ (VOID **) &StallPpi
+ );
+
+ if (!EFI_ERROR (Status)) {
+
+ Status = PeiServicesReInstallPpi (
+ StallPeiPpiDescriptor,
+ &mPpiStall[0]
+ );
+ } else {
+
+ Status = PeiServicesInstallPpi (&mPpiStall[0]);
+ }
+ return Status;
+ }
+
+ //
+ // Initialize System Phys
+ //
+
+ // Program USB Phy
+ InitializeUSBPhy();
+
+ //
+ // Do platform specific logic to create a boot mode
+ //
+ Status = UpdateBootMode ((EFI_PEI_SERVICES**)PeiServices, &BootMode);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Signal possible dependent modules that there has been a
+ // final boot mode determination
+ //
+ if (!EFI_ERROR(Status)) {
+ Status = PeiServicesInstallPpi (&mPpiBootMode[0]);
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ if (BootMode != BOOT_ON_S3_RESUME) {
+ QNCClearSmiAndWake ();
+ }
+
+ DEBUG ((EFI_D_INFO, "MRC Entry\n"));
+ MemoryInit ((EFI_PEI_SERVICES**)PeiServices);
+
+ //
+ // Do Early PCIe init.
+ //
+ DEBUG ((EFI_D_INFO, "Early PCIe controller initialization\n"));
+ PlatformPciExpressEarlyInit (PlatformType);
+
+
+ DEBUG ((EFI_D_INFO, "Platform Erratas After MRC\n"));
+ PlatformErratasPostMrc ();
+
+ //
+ // Now that all of the pre-permanent memory activities have
+ // been taken care of, post a call-back for the permanent-memory
+ // resident services, such as HOB construction.
+ // PEI Core will switch stack after this PEIM exit. After that the MTRR
+ // can be set.
+ //
+ Status = PeiServicesNotifyPpi (&mMemoryDiscoveredNotifyList[0]);
+ ASSERT_EFI_ERROR (Status);
+/*
+
+ if (BootMode != BOOT_ON_S3_RESUME) {
+ Status = PeiServicesNotifyPpi (mEndOfPeiSignalPpiNotifyList);
+ ASSERT_EFI_ERROR (Status);
+ }
+*/
+ if (BootMode == BOOT_IN_RECOVERY_MODE) {
+ PeiServicesRegisterForShadow (FileHandle);
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+EndOfPeiSignalPpiNotifyCallback (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ )
+{
+ EFI_STATUS Status;
+
+ DEBUG ((EFI_D_INFO, "End of PEI Signal Callback\n"));
+
+ //
+ // Restore the flash region to be UC
+ // for both normal boot as we build a Resource Hob to
+ // describe this region as UC to DXE core.
+ //
+ WriteBackInvalidateDataCacheRange (
+ (VOID *) (UINTN) PcdGet32 (PcdFlashAreaBaseAddress),
+ PcdGet32 (PcdFlashAreaSize)
+ );
+
+ Status = MtrrSetMemoryAttribute (PcdGet32 (PcdFlashAreaBaseAddress), PcdGet32 (PcdFlashAreaSize), CacheUncacheable);
+ ASSERT_EFI_ERROR (Status);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function will initialize USB Phy registers associated with QuarkSouthCluster.
+
+ @param VOID No Argument
+
+ @retval EFI_SUCCESS All registers have been initialized
+**/
+VOID
+EFIAPI
+InitializeUSBPhy (
+ VOID
+ )
+{
+ UINT32 RegData32;
+
+ /** In order to configure the PHY to use clk120 (ickusbcoreclk) as PLL reference clock
+ * and Port2 as a USB device port, the following sequence must be followed
+ *
+ **/
+
+ // Sideband register write to USB AFE (Phy)
+ RegData32 = QNCAltPortRead (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_GLOBAL_PORT);
+ RegData32 &= ~(BIT1);
+ //
+ // Sighting #4930631 PDNRESCFG [8:7] of USB2_GLOBAL_PORT = 11b.
+ // For port 0 & 1 as host and port 2 as device.
+ //
+ RegData32 |= (BIT8 | BIT7);
+ QNCAltPortWrite (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_GLOBAL_PORT, RegData32);
+
+ //
+ // Sighting #4930653 Required BIOS change on Disconnect vref to change to 600mV.
+ //
+ RegData32 = QNCAltPortRead (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_COMPBG);
+ RegData32 &= ~(BIT10 | BIT9 | BIT8 | BIT7);
+ RegData32 |= (BIT10 | BIT7);
+ QNCAltPortWrite (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_COMPBG, RegData32);
+
+ // Sideband register write to USB AFE (Phy)
+ // (pllbypass) to bypass/Disable PLL before switch
+ RegData32 = QNCAltPortRead (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_PLL2);
+ RegData32 |= BIT29;
+ QNCAltPortWrite (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_PLL2, RegData32);
+
+ // Sideband register write to USB AFE (Phy)
+ // (coreclksel) to select 120MHz (ickusbcoreclk) clk source.
+ // (Default 0 to select 96MHz (ickusbclk96_npad/ppad))
+ RegData32 = QNCAltPortRead (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_PLL1);
+ RegData32 |= BIT1;
+ QNCAltPortWrite (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_PLL1, RegData32);
+
+ // Sideband register write to USB AFE (Phy)
+ // (divide by 8) to achieve internal 480MHz clock
+ // for 120MHz input refclk. (Default: 4'b1000 (divide by 10) for 96MHz)
+ RegData32 = QNCAltPortRead (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_PLL1);
+ RegData32 &= ~(BIT5 | BIT4 | BIT3);
+ RegData32 |= BIT6;
+ QNCAltPortWrite (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_PLL1, RegData32);
+
+ // Sideband register write to USB AFE (Phy)
+ // Clear (pllbypass)
+ RegData32 = QNCAltPortRead (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_PLL2);
+ RegData32 &= ~BIT29;
+ QNCAltPortWrite (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_PLL2, RegData32);
+
+ // Sideband register write to USB AFE (Phy)
+ // Set (startlock) to force the PLL FSM to restart the lock
+ // sequence due to input clock/freq switch.
+ RegData32 = QNCAltPortRead (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_PLL2);
+ RegData32 |= BIT24;
+ QNCAltPortWrite (QUARK_SC_USB_AFE_SB_PORT_ID, USB2_PLL2, RegData32);
+
+ // At this point the PLL FSM and COMP FSM will complete
+
+}
+
+/**
+ This function provides early platform Thermal sensor initialisation.
+**/
+VOID
+EFIAPI
+EarlyPlatformThermalSensorInit (
+ VOID
+ )
+{
+ DEBUG ((EFI_D_INFO, "Early Platform Thermal Sensor Init\n"));
+
+ //
+ // Set Thermal sensor mode.
+ //
+ QNCThermalSensorSetRatiometricMode ();
+
+ //
+ // Enable RMU Thermal sensor with a Catastrophic Trip point.
+ //
+ QNCThermalSensorEnableWithCatastrophicTrip (PLATFORM_CATASTROPHIC_TRIP_CELSIUS);
+
+ //
+ // Lock all RMU Thermal sensor control & trip point registers.
+ //
+ QNCThermalSensorLockAllRegisters ();
+}
+
+/**
+ Print early platform info messages includeing the Stage1 module that's
+ running, MFH item list and platform data item list.
+**/
+VOID
+EFIAPI
+EarlyPlatformInfoMessages (
+ VOID
+ )
+{
+ DEBUG_CODE_BEGIN ();
+ QUARK_EDKII_STAGE1_HEADER *Edk2ImageHeader;
+
+ //
+ // Find which 'Stage1' image we are running and print the details
+ //
+ Edk2ImageHeader = (QUARK_EDKII_STAGE1_HEADER *) PcdGet32 (PcdEsramStage1Base);
+ DEBUG ((EFI_D_INFO, "\n************************************************************\n"));
+
+ switch ((UINT8)Edk2ImageHeader->ImageIndex & QUARK_STAGE1_IMAGE_TYPE_MASK) {
+ case QUARK_STAGE1_BOOT_IMAGE_TYPE:
+ DEBUG ((EFI_D_INFO, "**** Quark EDKII Stage 1 Boot Image %d ****\n", ((UINT8)Edk2ImageHeader->ImageIndex & ~(QUARK_STAGE1_IMAGE_TYPE_MASK))));
+ break;
+
+ case QUARK_STAGE1_RECOVERY_IMAGE_TYPE:
+ DEBUG ((EFI_D_INFO, "**** Quark EDKII Stage 1 Recovery Image %d ****\n", ((UINT8)Edk2ImageHeader->ImageIndex & ~(QUARK_STAGE1_IMAGE_TYPE_MASK))));
+ break;
+
+ default:
+ DEBUG ((EFI_D_INFO, "**** Quark EDKII Unknown Stage 1 Image !!!! ****\n"));
+ break;
+ }
+ DEBUG (
+ (EFI_D_INFO,
+ "**** Quark EDKII Stage 2 Image 0x%08X:0x%08X ****\n" ,
+ (UINTN) PcdGet32 (PcdFlashFvMainBase),
+ (UINTN) PcdGet32 (PcdFlashFvMainSize)
+ ));
+
+ DEBUG (
+ (EFI_D_INFO,
+ "**** Quark EDKII Payload Image 0x%08X:0x%08X ****\n" ,
+ (UINTN) PcdGet32 (PcdFlashFvPayloadBase),
+ (UINTN) PcdGet32 (PcdFlashFvPayloadSize)
+ ));
+
+ DEBUG ((EFI_D_INFO, "************************************************************\n\n"));
+
+ DEBUG_CODE_END ();
+}
+
+/**
+ Check if system reset due to error condition.
+
+ @param ClearErrorBits If TRUE clear error flags and value bits.
+
+ @retval TRUE if system reset due to error condition.
+ @retval FALSE if NO reset error conditions.
+**/
+BOOLEAN
+CheckForResetDueToErrors (
+ IN BOOLEAN ClearErrorBits
+ )
+{
+ UINT32 RegValue;
+ BOOLEAN ResetDueToError;
+
+ ResetDueToError = FALSE;
+
+ //
+ // Check if RMU reset system due to access violations.
+ // RMU updates a SOC Unit register before reseting the system.
+ //
+ RegValue = QNCAltPortRead (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_CFG_STICKY_RW);
+ if ((RegValue & B_CFG_STICKY_RW_VIOLATION) != 0) {
+ ResetDueToError = TRUE;
+
+ DEBUG (
+ (EFI_D_ERROR,
+ "\nReset due to access violation: %s %s %s %s\n",
+ ((RegValue & B_CFG_STICKY_RW_IMR_VIOLATION) != 0) ? L"'IMR'" : L".",
+ ((RegValue & B_CFG_STICKY_RW_DECC_VIOLATION) != 0) ? L"'DECC'" : L".",
+ ((RegValue & B_CFG_STICKY_RW_SMM_VIOLATION) != 0) ? L"'SMM'" : L".",
+ ((RegValue & B_CFG_STICKY_RW_HMB_VIOLATION) != 0) ? L"'HMB'" : L"."
+ ));
+
+ //
+ // Clear error bits.
+ //
+ if (ClearErrorBits) {
+ RegValue &= ~(B_CFG_STICKY_RW_VIOLATION);
+ QNCAltPortWrite (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_CFG_STICKY_RW, RegValue);
+ }
+ }
+
+ return ResetDueToError;
+}
+
+/**
+ This function provides early platform initialization.
+
+ @param PlatformInfo Pointer to platform Info structure.
+
+**/
+VOID
+EFIAPI
+EarlyPlatformInit (
+ VOID
+ )
+{
+ EFI_PLATFORM_TYPE PlatformType;
+
+ PlatformType = (EFI_PLATFORM_TYPE) PcdGet16 (PcdPlatformType);
+
+ DEBUG ((EFI_D_INFO, "EarlyPlatformInit for PlatType=0x%02x\n", (UINTN) PlatformType));
+
+ //
+ // Check if system reset due to error condition.
+ //
+ if (CheckForResetDueToErrors (TRUE)) {
+ if(FeaturePcdGet (WaitIfResetDueToError)) {
+ DEBUG ((EFI_D_ERROR, "Press any key to continue.\n"));
+ PlatformDebugPortGetChar8 ();
+ }
+ }
+
+ //
+ // Display platform info messages.
+ //
+ EarlyPlatformInfoMessages ();
+
+ //
+ // Early Legacy Gpio Init.
+ //
+ EarlyPlatformLegacyGpioInit (PlatformType);
+
+ //
+ // Early platform Legacy GPIO manipulation depending on GPIOs
+ // setup by EarlyPlatformLegacyGpioInit.
+ //
+ EarlyPlatformLegacyGpioManipulation (PlatformType);
+
+ //
+ // Early platform specific GPIO Controller init & manipulation.
+ // Combined for sharing of temp. memory bar.
+ //
+ EarlyPlatformGpioCtrlerInitAndManipulation (PlatformType);
+
+ //
+ // Early Thermal Sensor Init.
+ //
+ EarlyPlatformThermalSensorInit ();
+
+ //
+ // Early Lan Ethernet Mac Init.
+ //
+ EarlyPlatformMacInit (
+ PcdGetPtr (PcdIohEthernetMac0),
+ PcdGetPtr (PcdIohEthernetMac1)
+ );
+}
+
+/**
+ This function provides early platform Legacy GPIO initialisation.
+
+ @param PlatformType Platform type for GPIO init.
+
+**/
+VOID
+EFIAPI
+EarlyPlatformLegacyGpioInit (
+ IN CONST EFI_PLATFORM_TYPE PlatformType
+ )
+{
+ BOARD_LEGACY_GPIO_CONFIG *LegacyGpioConfig;
+ UINT32 NewValue;
+ UINT32 GpioBaseAddress;
+
+ //
+ // Assert if platform type outside table range.
+ //
+ ASSERT ((UINTN) PlatformType < mBoardLegacyGpioConfigTableLen);
+ LegacyGpioConfig = &mBoardLegacyGpioConfigTable[(UINTN) PlatformType];
+
+ GpioBaseAddress = (UINT32)PcdGet16 (PcdGbaIoBaseAddress);
+
+ NewValue = 0x0;
+ //
+ // Program QNC GPIO Registers.
+ //
+ NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_CGEN_CORE_WELL) & 0xFFFFFFFC) | LegacyGpioConfig->CoreWellEnable;
+ IoWrite32 (GpioBaseAddress + R_QNC_GPIO_CGEN_CORE_WELL, NewValue );
+ NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_CGIO_CORE_WELL) & 0xFFFFFFFC) | LegacyGpioConfig->CoreWellIoSelect;
+ IoWrite32 (GpioBaseAddress + R_QNC_GPIO_CGIO_CORE_WELL, NewValue);
+ NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_CGLVL_CORE_WELL) & 0xFFFFFFFC) | LegacyGpioConfig->CoreWellLvlForInputOrOutput;
+ IoWrite32 (GpioBaseAddress + R_QNC_GPIO_CGLVL_CORE_WELL, NewValue);
+ NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_CGTPE_CORE_WELL) & 0xFFFFFFFC) | LegacyGpioConfig->CoreWellTriggerPositiveEdge;
+ IoWrite32 (GpioBaseAddress + R_QNC_GPIO_CGTPE_CORE_WELL, NewValue );
+ NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_CGTNE_CORE_WELL) & 0xFFFFFFFC) | LegacyGpioConfig->CoreWellTriggerNegativeEdge;
+ IoWrite32 (GpioBaseAddress + R_QNC_GPIO_CGTNE_CORE_WELL, NewValue);
+ NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_CGGPE_CORE_WELL) & 0xFFFFFFFC) | LegacyGpioConfig->CoreWellGPEEnable;
+ IoWrite32 (GpioBaseAddress + R_QNC_GPIO_CGGPE_CORE_WELL, NewValue);
+ NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_CGSMI_CORE_WELL) & 0xFFFFFFFC) | LegacyGpioConfig->CoreWellSMIEnable;
+ IoWrite32 (GpioBaseAddress + R_QNC_GPIO_CGSMI_CORE_WELL, NewValue );
+ NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_CGTS_CORE_WELL) & 0xFFFFFFFC) | LegacyGpioConfig->CoreWellTriggerStatus;
+ IoWrite32 (GpioBaseAddress + R_QNC_GPIO_CGTS_CORE_WELL, NewValue);
+ NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_CNMIEN_CORE_WELL) & 0xFFFFFFFC) | LegacyGpioConfig->CoreWellNMIEnable;
+ IoWrite32 (GpioBaseAddress + R_QNC_GPIO_CNMIEN_CORE_WELL, NewValue);
+
+ NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_RGEN_RESUME_WELL) & 0xFFFFFFC0) | LegacyGpioConfig->ResumeWellEnable;
+ IoWrite32 (GpioBaseAddress + R_QNC_GPIO_RGEN_RESUME_WELL, NewValue );
+ NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_RGIO_RESUME_WELL) & 0xFFFFFFC0) | LegacyGpioConfig->ResumeWellIoSelect;
+ IoWrite32 (GpioBaseAddress + R_QNC_GPIO_RGIO_RESUME_WELL, NewValue) ;
+ NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_RGLVL_RESUME_WELL) & 0xFFFFFFC0) | LegacyGpioConfig->ResumeWellLvlForInputOrOutput;
+ IoWrite32 (GpioBaseAddress + R_QNC_GPIO_RGLVL_RESUME_WELL, NewValue);
+ NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_RGTPE_RESUME_WELL) & 0xFFFFFFC0) | LegacyGpioConfig->ResumeWellTriggerPositiveEdge;
+ IoWrite32 (GpioBaseAddress + R_QNC_GPIO_RGTPE_RESUME_WELL, NewValue );
+ NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_RGTNE_RESUME_WELL) & 0xFFFFFFC0) | LegacyGpioConfig->ResumeWellTriggerNegativeEdge;
+ IoWrite32 (GpioBaseAddress + R_QNC_GPIO_RGTNE_RESUME_WELL, NewValue) ;
+ NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_RGGPE_RESUME_WELL) & 0xFFFFFFC0) | LegacyGpioConfig->ResumeWellGPEEnable;
+ IoWrite32 (GpioBaseAddress + R_QNC_GPIO_RGGPE_RESUME_WELL, NewValue);
+ NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_RGSMI_RESUME_WELL) & 0xFFFFFFC0) | LegacyGpioConfig->ResumeWellSMIEnable;
+ IoWrite32 (GpioBaseAddress + R_QNC_GPIO_RGSMI_RESUME_WELL, NewValue );
+ NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_RGTS_RESUME_WELL) & 0xFFFFFFC0) | LegacyGpioConfig->ResumeWellTriggerStatus;
+ IoWrite32 (GpioBaseAddress + R_QNC_GPIO_RGTS_RESUME_WELL, NewValue) ;
+ NewValue = (IoRead32 (GpioBaseAddress + R_QNC_GPIO_RNMIEN_RESUME_WELL) & 0xFFFFFFC0) | LegacyGpioConfig->ResumeWellNMIEnable;
+ IoWrite32 (GpioBaseAddress + R_QNC_GPIO_RNMIEN_RESUME_WELL, NewValue);
+}
+
+/**
+ Performs any early platform specific Legacy GPIO manipulation.
+
+ @param PlatformType Platform type GPIO manipulation.
+
+**/
+VOID
+EFIAPI
+EarlyPlatformLegacyGpioManipulation (
+ IN CONST EFI_PLATFORM_TYPE PlatformType
+ )
+{
+ if (PlatformType == CrossHill) {
+
+ //
+ // Pull TPM reset low for 80us (equivalent to cold reset, Table 39
+ // Infineon SLB9645 Databook), then pull TPM reset high and wait for
+ // 150ms to give time for TPM to stabilise (Section 4.7.1 Infineon
+ // SLB9645 Databook states TPM is ready to receive command after 30ms
+ // but section 4.7 states some TPM commands may take longer to execute
+ // upto 150ms after test).
+ //
+
+ PlatformLegacyGpioSetLevel (
+ R_QNC_GPIO_RGLVL_RESUME_WELL,
+ PLATFORM_RESUMEWELL_TPM_RST_GPIO,
+ FALSE
+ );
+ MicroSecondDelay (80);
+
+ PlatformLegacyGpioSetLevel (
+ R_QNC_GPIO_RGLVL_RESUME_WELL,
+ PLATFORM_RESUMEWELL_TPM_RST_GPIO,
+ TRUE
+ );
+ MicroSecondDelay (150000);
+ }
+
+}
+
+/**
+ Performs any early platform specific GPIO Controller init & manipulation.
+
+ @param PlatformType Platform type for GPIO init & manipulation.
+
+**/
+VOID
+EFIAPI
+EarlyPlatformGpioCtrlerInitAndManipulation (
+ IN CONST EFI_PLATFORM_TYPE PlatformType
+ )
+{
+ UINT32 IohGpioBase;
+ UINT32 Data32;
+ UINT32 Addr;
+ BOARD_GPIO_CONTROLLER_CONFIG *GpioConfig;
+ UINT32 DevPcieAddr;
+ UINT16 SaveCmdReg;
+ UINT32 SaveBarReg;
+ UINT16 PciVid;
+ UINT16 PciDid;
+
+ ASSERT ((UINTN) PlatformType < mBoardGpioControllerConfigTableLen);
+ GpioConfig = &mBoardGpioControllerConfigTable[(UINTN) PlatformType];
+
+ IohGpioBase = (UINT32) PcdGet64 (PcdIohGpioMmioBase);
+
+ DevPcieAddr = PCI_LIB_ADDRESS (
+ PcdGet8 (PcdIohGpioBusNumber),
+ PcdGet8 (PcdIohGpioDevNumber),
+ PcdGet8 (PcdIohGpioFunctionNumber),
+ 0
+ );
+
+ //
+ // Do nothing if not a supported device.
+ //
+ PciVid = PciRead16 (DevPcieAddr + PCI_VENDOR_ID_OFFSET);
+ PciDid = PciRead16 (DevPcieAddr + PCI_DEVICE_ID_OFFSET);
+ if((PciVid != V_IOH_I2C_GPIO_VENDOR_ID) || (PciDid != V_IOH_I2C_GPIO_DEVICE_ID)) {
+ return;
+ }
+
+ //
+ // Save current settings for PCI CMD/BAR registers.
+ //
+ SaveCmdReg = PciRead16 (DevPcieAddr + PCI_COMMAND_OFFSET);
+ SaveBarReg = PciRead32 (DevPcieAddr + PcdGet8 (PcdIohGpioBarRegister));
+
+ //
+ // Use predefined tempory memory resource.
+ //
+ PciWrite32 ( DevPcieAddr + PcdGet8 (PcdIohGpioBarRegister), IohGpioBase);
+ PciWrite8 ( DevPcieAddr + PCI_COMMAND_OFFSET, EFI_PCI_COMMAND_MEMORY_SPACE);
+
+ //
+ // Gpio Controller Init Tasks.
+ //
+
+ //
+ // IEN- Interrupt Enable Register
+ //
+ Addr = IohGpioBase + GPIO_INTEN;
+ Data32 = *((volatile UINT32 *) (UINTN)(Addr)) & 0xFFFFFF00; // Keep reserved bits [31:8]
+ Data32 |= (GpioConfig->IntEn & 0x000FFFFF);
+ *((volatile UINT32 *) (UINTN)(Addr)) = Data32;
+
+ //
+ // ISTATUS- Interrupt Status Register
+ //
+ Addr = IohGpioBase + GPIO_INTSTATUS;
+ Data32 = *((volatile UINT32 *) (UINTN)(Addr)) & 0xFFFFFF00; // Keep reserved bits [31:8]
+ *((volatile UINT32 *) (UINTN)(Addr)) = Data32;
+
+ //
+ // GPIO SWPORTA Direction Register - GPIO_SWPORTA_DR
+ //
+ Addr = IohGpioBase + GPIO_SWPORTA_DR;
+ Data32 = *((volatile UINT32 *) (UINTN)(Addr)) & 0xFFFFFF00; // Keep reserved bits [31:8]
+ Data32 |= (GpioConfig->PortADR & 0x000FFFFF);
+ *((volatile UINT32 *) (UINTN)(Addr)) = Data32;
+
+ //
+ // GPIO SWPORTA Data Direction Register - GPIO_SWPORTA_DDR - default input
+ //
+ Addr = IohGpioBase + GPIO_SWPORTA_DDR;
+ Data32 = *((volatile UINT32 *) (UINTN)(Addr)) & 0xFFFFFF00; // Keep reserved bits [31:8]
+ Data32 |= (GpioConfig->PortADir & 0x000FFFFF);
+ *((volatile UINT32 *) (UINTN)(Addr)) = Data32;
+
+ //
+ // Interrupt Mask Register - GPIO_INTMASK - default interrupts unmasked
+ //
+ Addr = IohGpioBase + GPIO_INTMASK;
+ Data32 = *((volatile UINT32 *) (UINTN)(Addr)) & 0xFFFFFF00; // Keep reserved bits [31:8]
+ Data32 |= (GpioConfig->IntMask & 0x000FFFFF);
+ *((volatile UINT32 *) (UINTN)(Addr)) = Data32;
+
+ //
+ // Interrupt Level Type Register - GPIO_INTTYPE_LEVEL - default is level sensitive
+ //
+ Addr = IohGpioBase + GPIO_INTTYPE_LEVEL;
+ Data32 = *((volatile UINT32 *) (UINTN)(Addr)) & 0xFFFFFF00; // Keep reserved bits [31:8]
+ Data32 |= (GpioConfig->IntType & 0x000FFFFF);
+ *((volatile UINT32 *) (UINTN)(Addr)) = Data32;
+
+ //
+ // Interrupt Polarity Type Register - GPIO_INT_POLARITY - default is active low
+ //
+ Addr = IohGpioBase + GPIO_INT_POLARITY;
+ Data32 = *((volatile UINT32 *) (UINTN)(Addr)) & 0xFFFFFF00; // Keep reserved bits [31:8]
+ Data32 |= (GpioConfig->IntPolarity & 0x000FFFFF);
+ *((volatile UINT32 *) (UINTN)(Addr)) = Data32;
+
+ //
+ // Interrupt Debounce Type Register - GPIO_DEBOUNCE - default no debounce
+ //
+ Addr = IohGpioBase + GPIO_DEBOUNCE;
+ Data32 = *((volatile UINT32 *) (UINTN)(Addr)) & 0xFFFFFF00; // Keep reserved bits [31:8]
+ Data32 |= (GpioConfig->Debounce & 0x000FFFFF);
+ *((volatile UINT32 *) (UINTN)(Addr)) = Data32;
+
+ //
+ // Interrupt Clock Synchronisation Register - GPIO_LS_SYNC - default no sync with pclk_intr(APB bus clk)
+ //
+ Addr = IohGpioBase + GPIO_LS_SYNC;
+ Data32 = *((volatile UINT32 *) (UINTN)(Addr)) & 0xFFFFFF00; // Keep reserved bits [31:8]
+ Data32 |= (GpioConfig->LsSync & 0x000FFFFF);
+ *((volatile UINT32 *) (UINTN)(Addr)) = Data32;
+
+ //
+ // Gpio Controller Manipulation Tasks.
+ //
+
+ if (PlatformType == (EFI_PLATFORM_TYPE) Galileo) {
+ //
+ // Reset Cypress Expander on Galileo Platform
+ //
+ Addr = IohGpioBase + GPIO_SWPORTA_DR;
+ Data32 = *((volatile UINT32 *) (UINTN)(Addr));
+ Data32 |= BIT4; // Cypress Reset line controlled by GPIO<4>
+ *((volatile UINT32 *) (UINTN)(Addr)) = Data32;
+
+ Data32 = *((volatile UINT32 *) (UINTN)(Addr));
+ Data32 &= ~BIT4; // Cypress Reset line controlled by GPIO<4>
+ *((volatile UINT32 *) (UINTN)(Addr)) = Data32;
+
+ }
+
+ //
+ // Restore settings for PCI CMD/BAR registers
+ //
+ PciWrite32 ((DevPcieAddr + PcdGet8 (PcdIohGpioBarRegister)), SaveBarReg);
+ PciWrite16 (DevPcieAddr + PCI_COMMAND_OFFSET, SaveCmdReg);
+}
+
+/**
+ Performs any early platform init of SoC Ethernet Mac devices.
+
+ @param IohMac0Address Mac address to program into Mac0 device.
+ @param IohMac1Address Mac address to program into Mac1 device.
+
+**/
+VOID
+EFIAPI
+EarlyPlatformMacInit (
+ IN CONST UINT8 *IohMac0Address,
+ IN CONST UINT8 *IohMac1Address
+ )
+{
+ BOOLEAN SetMacAddr;
+
+ //
+ // Set chipset MAC0 address if configured.
+ //
+ SetMacAddr =
+ (CompareMem (ChipsetDefaultMac, IohMac0Address, sizeof (ChipsetDefaultMac))) != 0;
+ if (SetMacAddr) {
+ if ((*(IohMac0Address) & BIT0) != 0) {
+ DEBUG ((EFI_D_ERROR, "HALT: Multicast Mac Address configured for Ioh MAC [B:%d, D:%d, F:%d]\n",
+ (UINTN) IOH_MAC0_BUS_NUMBER,
+ (UINTN) IOH_MAC0_DEVICE_NUMBER,
+ (UINTN) IOH_MAC0_FUNCTION_NUMBER
+ ));
+ ASSERT (FALSE);
+ } else {
+ SetLanControllerMacAddr (
+ IOH_MAC0_BUS_NUMBER,
+ IOH_MAC0_DEVICE_NUMBER,
+ IOH_MAC0_FUNCTION_NUMBER,
+ IohMac0Address,
+ (UINT32) PcdGet64(PcdIohMac0MmioBase)
+ );
+ }
+ } else {
+ DEBUG ((EFI_D_WARN, "WARNING: Ioh MAC [B:%d, D:%d, F:%d] NO HW ADDR CONFIGURED!!!\n",
+ (UINTN) IOH_MAC0_BUS_NUMBER,
+ (UINTN) IOH_MAC0_DEVICE_NUMBER,
+ (UINTN) IOH_MAC0_FUNCTION_NUMBER
+ ));
+ }
+
+ //
+ // Set chipset MAC1 address if configured.
+ //
+ SetMacAddr =
+ (CompareMem (ChipsetDefaultMac, IohMac1Address, sizeof (ChipsetDefaultMac))) != 0;
+ if (SetMacAddr) {
+ if ((*(IohMac1Address) & BIT0) != 0) {
+ DEBUG ((EFI_D_ERROR, "HALT: Multicast Mac Address configured for Ioh MAC [B:%d, D:%d, F:%d]\n",
+ (UINTN) IOH_MAC1_BUS_NUMBER,
+ (UINTN) IOH_MAC1_DEVICE_NUMBER,
+ (UINTN) IOH_MAC1_FUNCTION_NUMBER
+ ));
+ ASSERT (FALSE);
+ } else {
+ SetLanControllerMacAddr (
+ IOH_MAC1_BUS_NUMBER,
+ IOH_MAC1_DEVICE_NUMBER,
+ IOH_MAC1_FUNCTION_NUMBER,
+ IohMac1Address,
+ (UINT32) PcdGet64(PcdIohMac1MmioBase)
+ );
+ }
+ } else {
+ DEBUG ((EFI_D_WARN, "WARNING: Ioh MAC [B:%d, D:%d, F:%d] NO HW ADDR CONFIGURED!!!\n",
+ (UINTN) IOH_MAC1_BUS_NUMBER,
+ (UINTN) IOH_MAC1_DEVICE_NUMBER,
+ (UINTN) IOH_MAC1_FUNCTION_NUMBER
+ ));
+ }
+}
+
diff --git a/QuarkPlatformPkg/Platform/Pei/PlatformInit/PlatformEarlyInit.h b/QuarkPlatformPkg/Platform/Pei/PlatformInit/PlatformEarlyInit.h
new file mode 100644
index 0000000000..02d97e8e94
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Pei/PlatformInit/PlatformEarlyInit.h
@@ -0,0 +1,307 @@
+/** @file
+The header file of Platform PEIM.
+
+Copyright (c) 2013 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+
+#ifndef __PLATFORM_EARLY_INIT_H__
+#define __PLATFORM_EARLY_INIT_H__
+
+#define PEI_STALL_RESOLUTION 1
+#define STALL_PEIM_SIGNATURE SIGNATURE_32('p','p','u','s')
+
+typedef struct {
+ UINT32 Signature;
+ EFI_FFS_FILE_HEADER *FfsHeader;
+ EFI_PEI_NOTIFY_DESCRIPTOR StallNotify;
+} STALL_CALLBACK_STATE_INFORMATION;
+
+#define STALL_PEIM_FROM_THIS(a) CR (a, STALL_CALLBACK_STATE_INFORMATION, StallNotify, STALL_PEIM_SIGNATURE)
+
+//
+// USB Phy Registers
+//
+#define USB2_GLOBAL_PORT 0x4001
+#define USB2_PLL1 0x7F02
+#define USB2_PLL2 0x7F03
+#define USB2_COMPBG 0x7F04
+
+/**
+ Peform the boot mode determination logic
+ If the box is closed, then
+ 1. If it's first time to boot, it's boot with full config .
+ 2. If the ChassisIntrution is selected, force to be a boot with full config
+ 3. Otherwise it's boot with no change.
+
+ @param PeiServices General purpose services available to every PEIM.
+
+ @param BootMode The detected boot mode.
+
+ @retval EFI_SUCCESS if the boot mode could be set
+**/
+EFI_STATUS
+UpdateBootMode (
+ IN EFI_PEI_SERVICES **PeiServices,
+ OUT EFI_BOOT_MODE *BootMode
+ );
+
+/**
+ This function reset the entire platform, including all processor and devices, and
+ reboots the system.
+
+ @param PeiServices General purpose services available to every PEIM.
+
+ @retval EFI_SUCCESS if it completed successfully.
+**/
+EFI_STATUS
+EFIAPI
+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
+PeimInitializeRecovery (
+ IN EFI_PEI_SERVICES **PeiServices
+ );
+
+/**
+ This function
+ 1. Calling MRC to initialize memory.
+ 2. Install EFI Memory.
+ 3. Create HOB of system memory.
+
+ @param PeiServices Pointer to the PEI Service Table
+
+ @retval EFI_SUCCESS If it completes successfully.
+
+**/
+EFI_STATUS
+MemoryInit (
+ IN EFI_PEI_SERVICES **PeiServices
+ );
+
+/** Return info derived from Installing Memory by MemoryInit.
+
+ @param[out] RmuMainBaseAddressPtr Return RmuMainBaseAddress to this location.
+ @param[out] SmramDescriptorPtr Return start of Smram descriptor list to this location.
+ @param[out] NumSmramRegionsPtr Return numbers of Smram regions to this location.
+
+ @return Address of RMU shadow region at the top of available memory.
+ @return List of Smram descriptors for each Smram region.
+ @return Numbers of Smram regions.
+**/
+VOID
+EFIAPI
+InfoPostInstallMemory (
+ OUT UINT32 *RmuMainBaseAddressPtr OPTIONAL,
+ OUT EFI_SMRAM_DESCRIPTOR **SmramDescriptorPtr OPTIONAL,
+ OUT UINTN *NumSmramRegionsPtr OPTIONAL
+ );
+
+/**
+ This function provides the implementation of AtaController PPI Enable Channel function.
+
+ @param PeiServices General purpose services available to every PEIM.
+ @param this Pointer to the local data for the interface.
+ @param ChannelMask This parameter is used to specify primary or slavery IDE channel.
+
+ @retval EFI_SUCCESS Procedure returned successfully.
+**/
+
+EFI_STATUS
+EnableAtaChannel (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_ATA_CONTROLLER_PPI *This,
+ IN UINT8 ChannelMask
+ );
+
+/**
+ This function provides the implementation of AtaController PPI Get IDE channel Register Base Address
+
+ @param PeiServices General purpose services available to every PEIM.
+ @param this Pointer to the local data for the interface.
+ @param IdeRegsBaseAddr Pointer to IDE_REGS_BASE_ADDR struct, which is used to record
+ IDE Command and Control regeisters Base Address.
+
+ @retval EFI_SUCCESS Procedure returned successfully.
+**/
+
+EFI_STATUS
+GetIdeRegsBaseAddr (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_ATA_CONTROLLER_PPI *This,
+ IN IDE_REGS_BASE_ADDR *IdeRegsBaseAddr
+ );
+
+VOID
+EFIAPI
+InitializeUSBPhy (
+ VOID
+ );
+
+/**
+ This function provides early platform initialisation.
+
+ @param PlatformInfo Pointer to platform Info structure.
+
+**/
+VOID
+EFIAPI
+EarlyPlatformInit (
+ VOID
+ );
+
+/**
+ This function provides early platform GPIO initialisation.
+
+ @param PlatformType Platform type for GPIO init.
+
+**/
+VOID
+EFIAPI
+EarlyPlatformLegacyGpioInit (
+ IN CONST EFI_PLATFORM_TYPE PlatformType
+ );
+
+/**
+ Performs any early platform specific GPIO manipulation.
+
+ @param PlatformType Platform type GPIO manipulation.
+
+**/
+VOID
+EFIAPI
+EarlyPlatformLegacyGpioManipulation (
+ IN CONST EFI_PLATFORM_TYPE PlatformType
+ );
+
+/**
+ Performs any early platform specific GPIO Controller init & manipulation.
+
+ @param PlatformType Platform type for GPIO init & manipulation.
+
+**/
+VOID
+EFIAPI
+EarlyPlatformGpioCtrlerInitAndManipulation (
+ IN CONST EFI_PLATFORM_TYPE PlatformType
+ );
+
+/**
+ Performs any early platform init of SoC Ethernet Mac devices.
+
+ @param IohMac0Address Mac address to program into Mac0 device.
+ @param IohMac1Address Mac address to program into Mac1 device.
+
+**/
+VOID
+EFIAPI
+EarlyPlatformMacInit (
+ IN CONST UINT8 *IohMac0Address,
+ IN CONST UINT8 *IohMac1Address
+ );
+
+/**
+ Find security headers using EFI_CAPSULE_VARIABLE_NAME variables and build Hobs.
+
+ @param PeiServices General purpose services available to every PEIM.
+
+ @retval 0 if no security headers found.
+ @return number of security header hobs built.
+**/
+UINTN
+EFIAPI
+FindCapsuleSecurityHeadersAndBuildHobs (
+ IN EFI_PEI_SERVICES **PeiServices
+ );
+
+/**
+ Build capsule security header hob.
+
+ @param SecHdr Pointer to security header.
+
+ @retval NULL if failure to build HOB.
+ @return pointer to built hob.
+**/
+VOID *
+EFIAPI
+BuildCapsuleSecurityHeaderHob (
+ IN VOID *SecHdr
+ );
+
+#endif
diff --git a/QuarkPlatformPkg/Platform/Pei/PlatformInit/PlatformEarlyInit.inf b/QuarkPlatformPkg/Platform/Pei/PlatformInit/PlatformEarlyInit.inf
new file mode 100644
index 0000000000..dd373defdb
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Pei/PlatformInit/PlatformEarlyInit.inf
@@ -0,0 +1,200 @@
+## @file
+# This is the Platform PEIM to initialize whole platform on PEI phase.
+#
+# This PEIM includes 3 parts, pre memory initialization, MRC
+# wrapper and post memory initialization.
+# On pre memory, following action is performed,
+# 1. Initizluize GMCH.
+# 2. Detect boot mode.
+# 3. Detect video adapter to determine whether we need pre allocated
+# memory.
+#
+# After that MRC wrapper calls MRC to initialize memory and install a PPI
+# notify to do post memory
+# initialization. MRC wrapper performance following actions,
+# 1. Install EFI Memory.
+# 2. Create HOB of system memory.
+#
+# On post memory, following action is performed,
+# 1. QNC initialization after MRC.
+# 2. SIO initialization.
+# 3. Install ResetSystem and FinvFv PPI, relocate Stall to memory on
+# recovery boot mode.
+# 4. Set MTRR for PEI
+# 5. Create FV HOB and Flash HOB
+# 6. Install RecoveryModule and AtaController PPI if on recovery boot mode.
+#
+# This PEIM does not have any register access directly, it depends on
+# IntelQNCLib, QNCAccess libraries to access Chipset
+# registers.
+#
+# Platform.c - Provide main flow and entrypoint of PEIM.
+# MemoryCallback.c - Includes a memory call back function notified when
+# MRC is done.
+# Recovery.c - provides the platform recoveyr functionality.
+# MrcWrapper.c - Contains the logic to call MRC PPI and do Framework
+# memory specific stuff like build memory map, build
+# resource description hob for DXE phase,etc.
+# Bootmode.c - Detect boot mode.
+# Copyright (c) 2013 Intel Corporation.
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = PlatformEarlyInitPei
+ FILE_GUID = 9618C0DC-50A4-496c-994F-7241F282ED01
+ MODULE_TYPE = PEIM
+ VERSION_STRING = 1.0
+ ENTRY_POINT = PeiInitPlatform
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ Generic/Recovery.c
+ PlatformErratas.c
+ MrcWrapper.c
+ MrcWrapper.h
+ PlatformEarlyInit.c
+ PlatformEarlyInit.h
+ MemoryCallback.c
+ BootMode.c
+ CommonHeader.h
+ PeiFvSecurity.c
+ PeiFvSecurity.h
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ UefiCpuPkg/UefiCpuPkg.dec
+ IntelFrameworkPkg/IntelFrameworkPkg.dec
+ IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
+ QuarkPlatformPkg/QuarkPlatformPkg.dec
+ QuarkSocPkg/QuarkSocPkg.dec
+
+[LibraryClasses]
+ ResetSystemLib
+ PrintLib
+ TimerLib
+ RecoveryOemHookLib
+ PcdLib
+ IntelQNCLib
+ ReportStatusCodeLib
+ PciLib
+ PciExpressLib
+ IoLib
+ PciCf8Lib
+ HobLib
+ BaseMemoryLib
+ PeiServicesTablePointerLib
+ PeiServicesLib
+ BaseLib
+ PeimEntryPoint
+ DebugLib
+ MemoryAllocationLib
+ PerformanceLib
+ CacheMaintenanceLib
+ MtrrLib
+ QNCAccessLib
+ PlatformHelperLib
+ PlatformPcieHelperLib
+
+[Guids]
+ gEfiMemoryConfigDataGuid # ALWAYS_CONSUMED L"MemoryConfig"
+ gEfiAcpiVariableGuid # ALWAYS_CONSUMED L"AcpiGlobalVariab"
+ gEfiMemoryTypeInformationGuid # ALWAYS_CONSUMED L"MemoryTypeInformation"
+ gEfiMemoryConfigDataGuid # SOMETIMES_PRODUCED Hob: GUID_EXTENSION
+ gEfiSmmPeiSmramMemoryReserveGuid # ALWAYS_PRODUCED Hob: GUID_EXTENSION
+ gEfiFirmwareFileSystem2Guid # ALWAYS_CONSUMED
+ gEfiCapsuleGuid # ALWAYS_CONSUMED
+ gPeiCapsuleOnDataCDGuid
+ gPeiCapsuleOnFatIdeDiskGuid
+ gPeiCapsuleOnFatUsbDiskGuid
+ gEfiMemoryOverwriteControlDataGuid # SOMETIMES_CONSUMED
+ gEfiQuarkCapsuleGuid
+
+[Ppis]
+ gQNCMemoryInitPpiGuid # PPI ALWAYS_CONSUMED
+ gEfiPeiMemoryDiscoveredPpiGuid # PPI ALWAYS_PRODUCED
+ gPeiAtaControllerPpiGuid # PPI SOMETIMES_PRODUCED
+ gEfiPeiStallPpiGuid # PPI ALWAYS_PRODUCED
+ gEfiPeiDeviceRecoveryModulePpiGuid # PPI SOMETIMES_CONSUMED
+ gEfiPeiRecoveryModulePpiGuid # PPI SOMETIMES_PRODUCED
+ gEfiPeiResetPpiGuid # PPI ALWAYS_PRODUCED
+ gEfiPeiReadOnlyVariable2PpiGuid # PPI ALWAYS_CONSUMED
+ gEfiPeiBootInRecoveryModePpiGuid # PPI SOMETIMES_PRODUCED
+ gEfiPeiMasterBootModePpiGuid # PPI ALWAYS_PRODUCED
+ gEfiPeiFirmwareVolumeInfoPpiGuid
+ gEfiEndOfPeiSignalPpiGuid
+ gEfiPeiVirtualBlockIoPpiGuid
+ gPeiCapsulePpiGuid # PPI ALWAYS_CONSUMED
+
+[FeaturePcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdRecoveryOnFatUsbDisk
+ gEfiMdeModulePkgTokenSpaceGuid.PcdRecoveryOnDataCD
+ gEfiMdeModulePkgTokenSpaceGuid.PcdRecoveryOnFatFloppyDisk
+ gEfiMdeModulePkgTokenSpaceGuid.PcdRecoveryOnIdeDisk
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFrameworkCompatibilitySupport
+ gQuarkPlatformTokenSpaceGuid.WaitIfResetDueToError
+
+[Pcd]
+ gQuarkPlatformTokenSpaceGuid.PcdEsramStage1Base
+ gQuarkPlatformTokenSpaceGuid.PcdFlashAreaSize
+ gQuarkPlatformTokenSpaceGuid.PcdFlashAreaBaseAddress
+ gQuarkPlatformTokenSpaceGuid.PcdEccScrubBlkSize
+ gQuarkPlatformTokenSpaceGuid.PcdEccScrubInterval
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+ gQuarkPlatformTokenSpaceGuid.PcdFlashQNCMicrocodeSize
+ gEfiQuarkNcSocIdTokenSpaceGuid.PcdPmbaIoBaseAddress
+ gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+ gEfiQuarkNcSocIdTokenSpaceGuid.PcdPciHostBridgeIoBase
+ gEfiQuarkNcSocIdTokenSpaceGuid.PcdPciHostBridgeIoSize
+ gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohUartFunctionNumber
+ gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohUartBusNumber
+ gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohUartDevNumber
+ gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohGpioBusNumber
+ gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohGpioDevNumber
+ gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohGpioFunctionNumber
+ gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohGpioBarRegister
+ gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohGpioMmioBase
+ gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohMac0MmioBase
+ gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohMac1MmioBase
+ gEfiQuarkSCSocIdTokenSpaceGuid.PcdPeiQNCUsbControllerMemoryBaseAddress
+ gEfiQuarkNcSocIdTokenSpaceGuid.PcdRcbaMmioBaseAddress
+ gEfiQuarkNcSocIdTokenSpaceGuid.PcdPciHostBridgeMemory32Base
+ gEfiQuarkNcSocIdTokenSpaceGuid.PcdPciHostBridgeMemory32Size
+ gEfiQuarkNcSocIdTokenSpaceGuid.PcdPciHostBridgeMemory64Base
+ gEfiQuarkNcSocIdTokenSpaceGuid.PcdPciHostBridgeMemory64Size
+ gEfiQuarkNcSocIdTokenSpaceGuid.PcdPciExpressSize
+ gEfiQuarkNcSocIdTokenSpaceGuid.PcdGbaIoBaseAddress
+ gEfiQuarkNcSocIdTokenSpaceGuid.PcdQuarkMicrocodeFile
+ gEfiQuarkNcSocIdTokenSpaceGuid.PcdTSegSize
+ gEfiQuarkNcSocIdTokenSpaceGuid.PcdESramMemorySize
+ gQuarkPlatformTokenSpaceGuid.PcdFlashFvRecoverySize
+ gQuarkPlatformTokenSpaceGuid.PcdFlashFvRecoveryBase
+ gQuarkPlatformTokenSpaceGuid.PcdFlashFvMainSize
+ gQuarkPlatformTokenSpaceGuid.PcdFlashFvMainBase
+ gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdBootState
+ gQuarkPlatformTokenSpaceGuid.PcdFlashFvPayloadBase
+ gQuarkPlatformTokenSpaceGuid.PcdFlashFvPayloadSize
+ gQuarkPlatformTokenSpaceGuid.PcdEnableFastBoot
+ gQuarkPlatformTokenSpaceGuid.PcdPlatformType
+ gEfiQuarkNcSocIdTokenSpaceGuid.PcdMrcParameters
+ gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohEthernetMac0
+ gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohEthernetMac1
+
+[Depex]
+ gEfiPeiReadOnlyVariable2PpiGuid AND gQNCMemoryInitPpiGuid
diff --git a/QuarkPlatformPkg/Platform/Pei/PlatformInit/PlatformErratas.c b/QuarkPlatformPkg/Platform/Pei/PlatformInit/PlatformErratas.c
new file mode 100644
index 0000000000..ba8399331a
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/Pei/PlatformInit/PlatformErratas.c
@@ -0,0 +1,184 @@
+/** @file
+Platform Erratas performed by early init PEIM driver.
+
+Copyright (c) 2013 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "CommonHeader.h"
+#include "PlatformEarlyInit.h"
+
+//
+// Constants.
+//
+
+//
+// Platform EHCI Packet Buffer OUT/IN Thresholds, values in number of DWORDs.
+//
+#define EHCI_OUT_THRESHOLD_VALUE (0x7f)
+#define EHCI_IN_THRESHOLD_VALUE (0x7f)
+
+//
+// Platform init USB device interrupt masks.
+//
+#define V_IOH_USBDEVICE_D_INTR_MSK_UDC_REG (0x0000007f)
+#define V_IOH_USBDEVICE_EP_INTR_MSK_UDC_REG (B_IOH_USBDEVICE_EP_INTR_MSK_UDC_REG_OUT_EP_MASK | B_IOH_USBDEVICE_EP_INTR_MSK_UDC_REG_IN_EP_MASK)
+
+//
+// Global variables defined within this source module.
+//
+
+UINTN IohEhciPciReg[IOH_MAX_EHCI_USB_CONTROLLERS] = {
+ PCI_LIB_ADDRESS (IOH_USB_BUS_NUMBER, IOH_USB_EHCI_DEVICE_NUMBER, IOH_EHCI_FUNCTION_NUMBER, 0),
+};
+
+UINTN IohUsbDevicePciReg[IOH_MAX_USBDEVICE_USB_CONTROLLERS] = {
+ PCI_LIB_ADDRESS (IOH_USB_BUS_NUMBER, IOH_USBDEVICE_DEVICE_NUMBER, IOH_USBDEVICE_FUNCTION_NUMBER, 0),
+};
+
+//
+// Routines local to this source module.
+//
+
+/** Perform USB erratas after MRC init.
+
+**/
+VOID
+PlatformUsbErratasPostMrc (
+ VOID
+ )
+{
+ UINT32 Index;
+ UINT32 TempBar0Addr;
+ UINT16 SaveCmdReg;
+ UINT32 SaveBar0Reg;
+
+ TempBar0Addr = PcdGet32(PcdPeiQNCUsbControllerMemoryBaseAddress);
+
+ //
+ // Apply EHCI controller erratas.
+ //
+ for (Index = 0; Index < IOH_MAX_EHCI_USB_CONTROLLERS; Index++, TempBar0Addr += IOH_USB_CONTROLLER_MMIO_RANGE) {
+
+ if ((PciRead16 (IohEhciPciReg[Index] + R_IOH_USB_VENDOR_ID)) != V_IOH_USB_VENDOR_ID) {
+ continue; // Device not enabled, skip.
+ }
+
+ //
+ // Save current settings for PCI CMD/BAR0 registers
+ //
+ SaveCmdReg = PciRead16 (IohEhciPciReg[Index] + R_IOH_USB_COMMAND);
+ SaveBar0Reg = PciRead32 (IohEhciPciReg[Index] + R_IOH_USB_MEMBAR);
+
+ //
+ // Temp. assign base address register, Enable Memory Space.
+ //
+ PciWrite32 ((IohEhciPciReg[Index] + R_IOH_USB_MEMBAR), TempBar0Addr);
+ PciWrite16 (IohEhciPciReg[Index] + R_IOH_USB_COMMAND, SaveCmdReg | B_IOH_USB_COMMAND_MSE);
+
+
+ //
+ // Set packet buffer OUT/IN thresholds.
+ //
+ MmioAndThenOr32 (
+ TempBar0Addr + R_IOH_EHCI_INSNREG01,
+ (UINT32) (~(B_IOH_EHCI_INSNREG01_OUT_THRESHOLD_MASK | B_IOH_EHCI_INSNREG01_IN_THRESHOLD_MASK)),
+ (UINT32) ((EHCI_OUT_THRESHOLD_VALUE << B_IOH_EHCI_INSNREG01_OUT_THRESHOLD_BP) | (EHCI_IN_THRESHOLD_VALUE << B_IOH_EHCI_INSNREG01_IN_THRESHOLD_BP))
+ );
+
+ //
+ // Restore settings for PCI CMD/BAR0 registers
+ //
+ PciWrite32 ((IohEhciPciReg[Index] + R_IOH_USB_MEMBAR), SaveBar0Reg);
+ PciWrite16 (IohEhciPciReg[Index] + R_IOH_USB_COMMAND, SaveCmdReg);
+ }
+
+ //
+ // Apply USB device controller erratas.
+ //
+ for (Index = 0; Index < IOH_MAX_USBDEVICE_USB_CONTROLLERS; Index++, TempBar0Addr += IOH_USB_CONTROLLER_MMIO_RANGE) {
+
+ if ((PciRead16 (IohUsbDevicePciReg[Index] + R_IOH_USB_VENDOR_ID)) != V_IOH_USB_VENDOR_ID) {
+ continue; // Device not enabled, skip.
+ }
+
+ //
+ // Save current settings for PCI CMD/BAR0 registers
+ //
+ SaveCmdReg = PciRead16 (IohUsbDevicePciReg[Index] + R_IOH_USB_COMMAND);
+ SaveBar0Reg = PciRead32 (IohUsbDevicePciReg[Index] + R_IOH_USB_MEMBAR);
+
+ //
+ // Temp. assign base address register, Enable Memory Space.
+ //
+ PciWrite32 ((IohUsbDevicePciReg[Index] + R_IOH_USB_MEMBAR), TempBar0Addr);
+ PciWrite16 (IohUsbDevicePciReg[Index] + R_IOH_USB_COMMAND, SaveCmdReg | B_IOH_USB_COMMAND_MSE);
+
+ //
+ // Erratas for USB Device interrupt registers.
+ //
+
+ //
+ // 1st Mask interrupts.
+ //
+ MmioWrite32 (
+ TempBar0Addr + R_IOH_USBDEVICE_D_INTR_MSK_UDC_REG,
+ V_IOH_USBDEVICE_D_INTR_MSK_UDC_REG
+ );
+ //
+ // 2nd RW/1C of equivalent status bits.
+ //
+ MmioWrite32 (
+ TempBar0Addr + R_IOH_USBDEVICE_D_INTR_UDC_REG,
+ V_IOH_USBDEVICE_D_INTR_MSK_UDC_REG
+ );
+
+ //
+ // 1st Mask end point interrupts.
+ //
+ MmioWrite32 (
+ TempBar0Addr + R_IOH_USBDEVICE_EP_INTR_MSK_UDC_REG,
+ V_IOH_USBDEVICE_EP_INTR_MSK_UDC_REG
+ );
+ //
+ // 2nd RW/1C of equivalent end point status bits.
+ //
+ MmioWrite32 (
+ TempBar0Addr + R_IOH_USBDEVICE_EP_INTR_UDC_REG,
+ V_IOH_USBDEVICE_EP_INTR_MSK_UDC_REG
+ );
+
+ //
+ // Restore settings for PCI CMD/BAR0 registers
+ //
+ PciWrite32 ((IohUsbDevicePciReg[Index] + R_IOH_USB_MEMBAR), SaveBar0Reg);
+ PciWrite16 (IohUsbDevicePciReg[Index] + R_IOH_USB_COMMAND, SaveCmdReg);
+ }
+}
+
+//
+// Routines exported by this source module.
+//
+
+/** Perform Platform Erratas after MRC.
+
+ @retval EFI_SUCCESS Operation success.
+
+**/
+EFI_STATUS
+EFIAPI
+PlatformErratasPostMrc (
+ VOID
+ )
+{
+ PlatformUsbErratasPostMrc ();
+ return EFI_SUCCESS;
+}
diff --git a/QuarkPlatformPkg/Platform/SpiFvbServices/FvbInfo.c b/QuarkPlatformPkg/Platform/SpiFvbServices/FvbInfo.c
new file mode 100644
index 0000000000..5c9e66c5c0
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/SpiFvbServices/FvbInfo.c
@@ -0,0 +1,338 @@
+/** @file
+Defines data structure that is the volume header found.These data is intent
+to decouple FVB driver with FV header.
+
+Copyright (c) 2013 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+
+**/
+
+#include <PiDxe.h>
+#include "FwBlockService.h"
+
+
+//#define FVB_MEDIA_BLOCK_SIZE PcdGet32(PcdFlashMinEraseSize)
+#define FVB_MEDIA_BLOCK_SIZE 0x1000
+
+typedef struct {
+ EFI_PHYSICAL_ADDRESS BaseAddress;
+ EFI_FIRMWARE_VOLUME_HEADER FvbInfo;
+ //
+ //EFI_FV_BLOCK_MAP_ENTRY ExtraBlockMap[n];//n=0
+ //
+ EFI_FV_BLOCK_MAP_ENTRY End[1];
+} EFI_FVB2_MEDIA_INFO;
+
+//
+// This data structure contains a template of all correct FV headers, which is used to restore
+// Fv header if it's corrupted.
+//
+EFI_FVB2_MEDIA_INFO mPlatformFvbMediaInfo[] = {
+ //
+ // Main BIOS FVB
+ //
+ {
+ 0,
+ {
+ {0,}, //ZeroVector[16]
+ EFI_FIRMWARE_FILE_SYSTEM2_GUID,
+ 0,
+ EFI_FVH_SIGNATURE,
+ 0x0004feff, // check MdePkg/Include/Pi/PiFirmwareVolume.h for details on EFI_FVB_ATTRIBUTES_2
+ sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY),
+ 0, //CheckSum, check the FD for the value.
+ 0, //ExtHeaderOffset
+ {0,}, //Reserved[1]
+ 2, //Revision
+ {
+ {
+ 0,
+ 0,
+ }
+ }
+ },
+ {
+ {
+ 0,
+ 0
+ }
+ }
+ },
+ //
+ // Systen NvStorage FVB
+ //
+ {
+ 0,
+ {
+ {0,}, //ZeroVector[16]
+ EFI_SYSTEM_NV_DATA_FV_GUID,
+ 0,
+ EFI_FVH_SIGNATURE,
+ 0x0004feff, // check MdePkg/Include/Pi/PiFirmwareVolume.h for details on EFI_FVB_ATTRIBUTES_2
+ sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY),
+ 0, //CheckSum which will be calucated dynamically.
+ 0, //ExtHeaderOffset
+ {0,}, //Reserved[1]
+ 2, //Revision
+ {
+ {
+ 0,
+ 0,
+ }
+ }
+ },
+ {
+ {
+ 0,
+ 0
+ }
+ }
+ },
+ //
+ // Recovery BIOS FVB
+ //
+ {
+ 0,
+ {
+ {0,}, //ZeroVector[16]
+ EFI_FIRMWARE_FILE_SYSTEM2_GUID,
+ 0,
+ EFI_FVH_SIGNATURE,
+ 0x0004feff, // check MdePkg/Include/Pi/PiFirmwareVolume.h for details on EFI_FVB_ATTRIBUTES_2
+ sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY),
+ 0, //CheckSum which will be calucated dynamically.
+ 0, //ExtHeaderOffset
+ {0,}, //Reserved[1]
+ 2, //Revision
+ {
+ {
+ 0,
+ 0,
+ }
+ }
+ },
+ {
+ {
+ 0,
+ 0
+ }
+ }
+ },
+ //
+ // Payload FVB
+ //
+ {
+ 0,
+ {
+ {0,}, //ZeroVector[16]
+ EFI_FIRMWARE_FILE_SYSTEM2_GUID,
+ 0,
+ EFI_FVH_SIGNATURE,
+ 0x0004feff, // check MdePkg/Include/Pi/PiFirmwareVolume.h for details on EFI_FVB_ATTRIBUTES_2
+ sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY),
+ 0, //CheckSum which will be calucated dynamically.
+ 0x60, //ExtHeaderOffset
+ {0,}, //Reserved[1]
+ 2, //Revision
+ {
+ {
+ 0,
+ 0,
+ }
+ }
+ },
+ {
+ {
+ 0,
+ 0
+ }
+ }
+ }
+};
+
+
+//
+// FTW working space and FTW spare space don't have FV header.
+// We need create one for them and use it for FVB protocol.
+//
+EFI_FVB2_MEDIA_INFO mPlatformFtwFvbInfo[] = {
+ //
+ // System variable FTW working FVB
+ //
+ {
+ 0,
+ {
+ {0,}, //ZeroVector[16]
+ EFI_SYSTEM_NV_DATA_FV_GUID,
+ 0,
+ EFI_FVH_SIGNATURE,
+ 0x0004feff, // check MdePkg/Include/Pi/PiFirmwareVolume.h for details on EFI_FVB_ATTRIBUTES_2
+ sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY),
+ 0, //CheckSum which will be calucated dynamically.
+ 0, //ExtHeaderOffset
+ {0,}, //Reserved[1]
+ 2, //Revision
+ {
+ {
+ 0,
+ 0,
+ }
+ }
+ },
+ {
+ {
+ 0,
+ 0
+ }
+ }
+ },
+ //
+ // Systen NV variable FTW spare FVB
+ //
+ {
+ 0,
+ {
+ {0,}, //ZeroVector[16]
+ EFI_SYSTEM_NV_DATA_FV_GUID,
+ 0,
+ EFI_FVH_SIGNATURE,
+ 0x0004feff, // check MdePkg/Include/Pi/PiFirmwareVolume.h for details on EFI_FVB_ATTRIBUTES_2
+ sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY),
+ 0, //CheckSum which will be calucated dynamically.
+ 0, //ExtHeaderOffset
+ {0,}, //Reserved[1]
+ 2, //Revision
+ {
+ {
+ 0,
+ 0,
+ }
+ }
+ },
+ {
+ {
+ 0,
+ 0
+ }
+ }
+ }
+};
+
+
+
+EFI_STATUS
+GetFtwFvbInfo (
+ IN EFI_PHYSICAL_ADDRESS FvBaseAddress,
+ OUT EFI_FIRMWARE_VOLUME_HEADER **FvbInfo
+ )
+{
+ UINTN Index;
+ EFI_FIRMWARE_VOLUME_HEADER *FvHeader;
+
+ //
+ // Init Fvb data
+ //
+ mPlatformFtwFvbInfo[0].BaseAddress = PcdGet32 (PcdFlashNvStorageFtwWorkingBase);
+ mPlatformFtwFvbInfo[0].FvbInfo.FvLength = PcdGet32 (PcdFlashNvStorageFtwWorkingSize);
+ mPlatformFtwFvbInfo[0].FvbInfo.BlockMap[0].NumBlocks = PcdGet32 (PcdFlashNvStorageFtwWorkingSize) / FVB_MEDIA_BLOCK_SIZE;
+ mPlatformFtwFvbInfo[0].FvbInfo.BlockMap[0].Length = FVB_MEDIA_BLOCK_SIZE;
+ ASSERT ((PcdGet32 (PcdFlashNvStorageFtwWorkingSize) % FVB_MEDIA_BLOCK_SIZE) == 0);
+
+ mPlatformFtwFvbInfo[1].BaseAddress = PcdGet32 (PcdFlashNvStorageFtwSpareBase);
+ mPlatformFtwFvbInfo[1].FvbInfo.FvLength = PcdGet32 (PcdFlashNvStorageFtwSpareSize);
+ mPlatformFtwFvbInfo[1].FvbInfo.BlockMap[0].NumBlocks = PcdGet32 (PcdFlashNvStorageFtwSpareSize) / FVB_MEDIA_BLOCK_SIZE;
+ mPlatformFtwFvbInfo[1].FvbInfo.BlockMap[0].Length = FVB_MEDIA_BLOCK_SIZE;
+ ASSERT ((PcdGet32 (PcdFlashNvStorageFtwSpareSize) % FVB_MEDIA_BLOCK_SIZE) == 0);
+
+ for (Index=0; Index < sizeof (mPlatformFtwFvbInfo)/sizeof (mPlatformFtwFvbInfo[0]); Index += 1) {
+ if (mPlatformFtwFvbInfo[Index].BaseAddress == FvBaseAddress) {
+ FvHeader = &mPlatformFtwFvbInfo[Index].FvbInfo;
+ //
+ // Update the checksum value of FV header.
+ //
+ FvHeader->Checksum = CalculateCheckSum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16));
+
+ *FvbInfo = FvHeader;
+
+ DEBUG ((EFI_D_INFO, "\nFTW BaseAddr: 0x%lx \n", FvBaseAddress));
+ DEBUG ((EFI_D_INFO, "FvLength: 0x%lx \n", (*FvbInfo)->FvLength));
+ DEBUG ((EFI_D_INFO, "HeaderLength: 0x%x \n", (*FvbInfo)->HeaderLength));
+ DEBUG ((EFI_D_INFO, "FvBlockMap[0].NumBlocks: 0x%x \n", (*FvbInfo)->BlockMap[0].NumBlocks));
+ DEBUG ((EFI_D_INFO, "FvBlockMap[0].BlockLength: 0x%x \n", (*FvbInfo)->BlockMap[0].Length));
+ DEBUG ((EFI_D_INFO, "FvBlockMap[1].NumBlocks: 0x%x \n", (*FvbInfo)->BlockMap[1].NumBlocks));
+ DEBUG ((EFI_D_INFO, "FvBlockMap[1].BlockLength: 0x%x \n\n", (*FvbInfo)->BlockMap[1].Length));
+
+ return EFI_SUCCESS;
+ }
+ }
+ return EFI_NOT_FOUND;
+}
+
+
+EFI_STATUS
+GetFvbInfo (
+ IN EFI_PHYSICAL_ADDRESS FvBaseAddress,
+ OUT EFI_FIRMWARE_VOLUME_HEADER **FvbInfo
+ )
+{
+ UINTN Index;
+ EFI_FIRMWARE_VOLUME_HEADER *FvHeader;
+
+ //
+ // Init Fvb data
+ //
+ mPlatformFvbMediaInfo[0].BaseAddress = PcdGet32 (PcdFlashFvMainBase);
+ mPlatformFvbMediaInfo[0].FvbInfo.FvLength = PcdGet32 (PcdFlashFvMainSize);
+ mPlatformFvbMediaInfo[0].FvbInfo.BlockMap[0].NumBlocks = PcdGet32 (PcdFlashFvMainSize) / FVB_MEDIA_BLOCK_SIZE;
+ mPlatformFvbMediaInfo[0].FvbInfo.BlockMap[0].Length = FVB_MEDIA_BLOCK_SIZE;
+ ASSERT ((PcdGet32 (PcdFlashFvMainSize) % FVB_MEDIA_BLOCK_SIZE) == 0);
+
+ mPlatformFvbMediaInfo[1].BaseAddress = PcdGet32 (PcdFlashNvStorageVariableBase);
+ mPlatformFvbMediaInfo[1].FvbInfo.FvLength = PcdGet32 (PcdFlashNvStorageVariableSize);
+ mPlatformFvbMediaInfo[1].FvbInfo.BlockMap[0].NumBlocks = PcdGet32 (PcdFlashNvStorageVariableSize) / FVB_MEDIA_BLOCK_SIZE;
+ mPlatformFvbMediaInfo[1].FvbInfo.BlockMap[0].Length = FVB_MEDIA_BLOCK_SIZE;
+ ASSERT ((PcdGet32 (PcdFlashNvStorageVariableSize) % FVB_MEDIA_BLOCK_SIZE) == 0);
+
+ mPlatformFvbMediaInfo[2].BaseAddress = PcdGet32 (PcdFlashFvRecoveryBase);
+ mPlatformFvbMediaInfo[2].FvbInfo.FvLength = PcdGet32 (PcdFlashFvRecoverySize);
+ mPlatformFvbMediaInfo[2].FvbInfo.BlockMap[0].NumBlocks = PcdGet32 (PcdFlashFvRecoverySize) / FVB_MEDIA_BLOCK_SIZE;
+ mPlatformFvbMediaInfo[2].FvbInfo.BlockMap[0].Length = FVB_MEDIA_BLOCK_SIZE;
+ ASSERT ((PcdGet32 (PcdFlashFvRecoverySize) % FVB_MEDIA_BLOCK_SIZE) == 0);
+
+ mPlatformFvbMediaInfo[3].BaseAddress = PcdGet32 (PcdFlashFvPayloadBase);
+ mPlatformFvbMediaInfo[3].FvbInfo.FvLength = PcdGet32 (PcdFlashFvPayloadSize);
+ mPlatformFvbMediaInfo[3].FvbInfo.BlockMap[0].NumBlocks = PcdGet32 (PcdFlashFvPayloadSize) / FVB_MEDIA_BLOCK_SIZE;
+ mPlatformFvbMediaInfo[3].FvbInfo.BlockMap[0].Length = FVB_MEDIA_BLOCK_SIZE;
+ ASSERT ((PcdGet32 (PcdFlashFvPayloadSize) % FVB_MEDIA_BLOCK_SIZE) == 0);
+
+ for (Index=0; Index < sizeof (mPlatformFvbMediaInfo)/sizeof (mPlatformFvbMediaInfo[0]); Index += 1) {
+ if (mPlatformFvbMediaInfo[Index].BaseAddress == FvBaseAddress) {
+ FvHeader = &mPlatformFvbMediaInfo[Index].FvbInfo;
+ //
+ // Update the checksum value of FV header.
+ //
+ FvHeader->Checksum = CalculateCheckSum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16));
+
+ *FvbInfo = FvHeader;
+
+ DEBUG ((EFI_D_INFO, "\nBaseAddr: 0x%lx \n", FvBaseAddress));
+ DEBUG ((EFI_D_INFO, "FvLength: 0x%lx \n", (*FvbInfo)->FvLength));
+ DEBUG ((EFI_D_INFO, "HeaderLength: 0x%x \n", (*FvbInfo)->HeaderLength));
+ DEBUG ((EFI_D_INFO, "FvBlockMap[0].NumBlocks: 0x%x \n", (*FvbInfo)->BlockMap[0].NumBlocks));
+ DEBUG ((EFI_D_INFO, "FvBlockMap[0].BlockLength: 0x%x \n", (*FvbInfo)->BlockMap[0].Length));
+ DEBUG ((EFI_D_INFO, "FvBlockMap[1].NumBlocks: 0x%x \n", (*FvbInfo)->BlockMap[1].NumBlocks));
+ DEBUG ((EFI_D_INFO, "FvBlockMap[1].BlockLength: 0x%x \n\n", (*FvbInfo)->BlockMap[1].Length));
+
+ return EFI_SUCCESS;
+ }
+ }
+ return EFI_NOT_FOUND;
+}
diff --git a/QuarkPlatformPkg/Platform/SpiFvbServices/FwBlockService.c b/QuarkPlatformPkg/Platform/SpiFvbServices/FwBlockService.c
new file mode 100644
index 0000000000..6d21bb01b6
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/SpiFvbServices/FwBlockService.c
@@ -0,0 +1,2066 @@
+/** @file
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+
+**/
+
+#include "FwBlockService.h"
+
+ESAL_FWB_GLOBAL *mFvbModuleGlobal;
+EFI_GUID gEfiFirmwareVolumeBlockProtocolGuid;
+EFI_GUID gEfiSmmFirmwareVolumeBlockProtocolGuid;
+
+EFI_FW_VOL_BLOCK_DEVICE mFvbDeviceTemplate = {
+ FVB_DEVICE_SIGNATURE, // Signature
+ //
+ // FV_DEVICE_PATH FvDevicePath
+ //
+ {
+ {
+ {
+ HARDWARE_DEVICE_PATH,
+ HW_MEMMAP_DP,
+ {
+ (UINT8)(sizeof (MEMMAP_DEVICE_PATH)),
+ (UINT8)(sizeof (MEMMAP_DEVICE_PATH) >> 8)
+ }
+ },
+ EfiMemoryMappedIO,
+ (EFI_PHYSICAL_ADDRESS) 0,
+ (EFI_PHYSICAL_ADDRESS) 0
+ },
+ {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ {
+ END_DEVICE_PATH_LENGTH,
+ 0
+ }
+ }
+ },
+ //
+ // UEFI_FV_DEVICE_PATH UefiFvDevicePath
+ //
+ {
+ {
+ {
+ MEDIA_DEVICE_PATH,
+ MEDIA_PIWG_FW_VOL_DP,
+ {
+ (UINT8)(sizeof (MEDIA_FW_VOL_DEVICE_PATH)),
+ (UINT8)(sizeof (MEDIA_FW_VOL_DEVICE_PATH) >> 8)
+ }
+ },
+ { 0 }
+ },
+ {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ {
+ END_DEVICE_PATH_LENGTH,
+ 0
+ }
+ }
+ },
+ 0, // Instance
+ //
+ // EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL FwVolBlockInstance
+ //
+ {
+ FvbProtocolGetAttributes,
+ FvbProtocolSetAttributes,
+ FvbProtocolGetPhysicalAddress,
+ FvbProtocolGetBlockSize,
+ FvbProtocolRead,
+ FvbProtocolWrite,
+ FvbProtocolEraseBlocks,
+ NULL
+ }
+};
+
+UINT32 mInSmmMode = 0;
+EFI_SMM_SYSTEM_TABLE2* mSmst = NULL;
+
+VOID
+PublishFlashDeviceInfo (
+ IN SPI_INIT_TABLE *Found
+ )
+/*++
+
+Routine Description:
+
+ Publish info on found flash device to other drivers via PcdSpiFlashDeviceSize.
+
+Arguments:
+ Found - Pointer to entry in mSpiInitTable for found flash part.
+
+Returns:
+ None
+
+--*/
+{
+ EFI_STATUS Status;
+
+ //
+ // Publish Byte Size of found flash device.
+ //
+ Status = PcdSet32S (PcdSpiFlashDeviceSize, (UINT32)(Found->BiosStartOffset + Found->BiosSize));
+ ASSERT_EFI_ERROR (Status);
+}
+
+VOID
+FvbVirtualddressChangeEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+/*++
+
+Routine Description:
+
+ Fixup internal data so that EFI and SAL can be call in virtual mode.
+ Call the passed in Child Notify event and convert the mFvbModuleGlobal
+ date items to there virtual address.
+
+ mFvbModuleGlobal->FvInstance[FVB_PHYSICAL] - Physical copy of instance data
+ mFvbModuleGlobal->FvInstance[FVB_VIRTUAL] - Virtual pointer to common
+ instance data.
+
+Arguments:
+
+ (Standard EFI notify event - EFI_EVENT_NOTIFY)
+
+Returns:
+
+ None
+
+--*/
+{
+ EFI_FW_VOL_INSTANCE *FwhInstance;
+ UINTN Index;
+
+ gRT->ConvertPointer (EFI_INTERNAL_POINTER, (VOID **) &mFvbModuleGlobal->FvInstance[FVB_VIRTUAL]);
+
+ //
+ // Convert the base address of all the instances
+ //
+ Index = 0;
+ FwhInstance = mFvbModuleGlobal->FvInstance[FVB_PHYSICAL];
+ while (Index < mFvbModuleGlobal->NumFv) {
+
+ gRT->ConvertPointer (EFI_INTERNAL_POINTER, (VOID **) &FwhInstance->FvBase[FVB_VIRTUAL]);
+ //
+ // SpiWrite and SpiErase always use Physical Address instead of
+ // Virtual Address, even in Runtime. So we need not convert pointer
+ // for FvWriteBase[FVB_VIRTUAL]
+ //
+ // EfiConvertPointer (0, (VOID **) &FwhInstance->FvWriteBase[FVB_VIRTUAL]);
+ //
+ FwhInstance = (EFI_FW_VOL_INSTANCE *)
+ (
+ (UINTN) ((UINT8 *) FwhInstance) + FwhInstance->VolumeHeader.HeaderLength +
+ (sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER))
+ );
+ Index++;
+ }
+
+ gRT->ConvertPointer (EFI_INTERNAL_POINTER, (VOID **) &mFvbModuleGlobal->FvbScratchSpace[FVB_VIRTUAL]);
+ //
+ // Convert SPI_PROTOCOL instance for runtime
+ //
+ gRT->ConvertPointer (EFI_INTERNAL_POINTER, (VOID **) &mFvbModuleGlobal->SpiProtocol);
+ gRT->ConvertPointer (EFI_INTERNAL_POINTER, (VOID **) &mFvbModuleGlobal);
+}
+
+VOID
+FvbMemWrite8 (
+ IN UINT64 Dest,
+ IN UINT8 Byte
+ )
+{
+ MmioWrite8 ((UINTN)Dest, Byte);
+
+ return ;
+}
+
+EFI_STATUS
+GetFvbInstance (
+ IN UINTN Instance,
+ IN ESAL_FWB_GLOBAL *Global,
+ OUT EFI_FW_VOL_INSTANCE **FwhInstance,
+ IN BOOLEAN Virtual
+ )
+/*++
+
+Routine Description:
+ Retrieves the physical address of a memory mapped FV
+
+Arguments:
+ Instance - The FV instance whose base address is going to be
+ returned
+ Global - Pointer to ESAL_FWB_GLOBAL that contains all
+ instance data
+ FwhInstance - The EFI_FW_VOL_INSTANCE fimrware instance structure
+ Virtual - Whether CPU is in virtual or physical mode
+
+Returns:
+ EFI_SUCCESS - Successfully returns
+ EFI_INVALID_PARAMETER - Instance not found
+
+--*/
+{
+ EFI_FW_VOL_INSTANCE *FwhRecord;
+
+ if (Instance >= Global->NumFv) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // Find the right instance of the FVB private data
+ //
+ FwhRecord = Global->FvInstance[Virtual];
+ while (Instance > 0) {
+ FwhRecord = (EFI_FW_VOL_INSTANCE *)
+ (
+ (UINTN) ((UINT8 *) FwhRecord) + FwhRecord->VolumeHeader.HeaderLength +
+ (sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER))
+ );
+ Instance--;
+ }
+
+ *FwhInstance = FwhRecord;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+FvbGetPhysicalAddress (
+ IN UINTN Instance,
+ OUT EFI_PHYSICAL_ADDRESS *Address,
+ IN ESAL_FWB_GLOBAL *Global,
+ IN BOOLEAN Virtual
+ )
+/*++
+
+Routine Description:
+ Retrieves the physical address of a memory mapped FV
+
+Arguments:
+ Instance - The FV instance whose base address is going to be
+ returned
+ Address - Pointer to a caller allocated EFI_PHYSICAL_ADDRESS
+ that on successful return, contains the base address
+ of the firmware volume.
+ Global - Pointer to ESAL_FWB_GLOBAL that contains all
+ instance data
+ Virtual - Whether CPU is in virtual or physical mode
+
+Returns:
+ EFI_SUCCESS - Successfully returns
+ EFI_INVALID_PARAMETER - Instance not found
+
+--*/
+{
+ EFI_FW_VOL_INSTANCE *FwhInstance;
+ EFI_STATUS Status;
+
+ FwhInstance = NULL;
+
+ //
+ // Find the right instance of the FVB private data
+ //
+ Status = GetFvbInstance (Instance, Global, &FwhInstance, Virtual);
+ ASSERT_EFI_ERROR (Status);
+ *Address = FwhInstance->FvBase[Virtual];
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+FvbGetVolumeAttributes (
+ IN UINTN Instance,
+ OUT EFI_FVB_ATTRIBUTES_2 *Attributes,
+ IN ESAL_FWB_GLOBAL *Global,
+ IN BOOLEAN Virtual
+ )
+/*++
+
+Routine Description:
+ Retrieves attributes, insures positive polarity of attribute bits, returns
+ resulting attributes in output parameter
+
+Arguments:
+ Instance - The FV instance whose attributes is going to be
+ returned
+ Attributes - Output buffer which contains attributes
+ Global - Pointer to ESAL_FWB_GLOBAL that contains all
+ instance data
+ Virtual - Whether CPU is in virtual or physical mode
+
+Returns:
+ EFI_SUCCESS - Successfully returns
+ EFI_INVALID_PARAMETER - Instance not found
+
+--*/
+{
+ EFI_FW_VOL_INSTANCE *FwhInstance;
+ EFI_STATUS Status;
+
+ FwhInstance = NULL;
+
+ //
+ // Find the right instance of the FVB private data
+ //
+ Status = GetFvbInstance (Instance, Global, &FwhInstance, Virtual);
+ ASSERT_EFI_ERROR (Status);
+ *Attributes = FwhInstance->VolumeHeader.Attributes;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+FvbGetLbaAddress (
+ IN UINTN Instance,
+ IN EFI_LBA Lba,
+ OUT UINTN *LbaAddress,
+ OUT UINTN *LbaWriteAddress,
+ OUT UINTN *LbaLength,
+ OUT UINTN *NumOfBlocks,
+ IN ESAL_FWB_GLOBAL *Global,
+ IN BOOLEAN Virtual
+ )
+/*++
+
+Routine Description:
+ Retrieves the starting address of an LBA in an FV
+
+Arguments:
+ Instance - The FV instance which the Lba belongs to
+ Lba - The logical block address
+ LbaAddress - On output, contains the physical starting address
+ of the Lba
+ LbaWriteAddress - On output, contains the physical starting address
+ of the Lba for writing
+ LbaLength - On output, contains the length of the block
+ NumOfBlocks - A pointer to a caller allocated UINTN in which the
+ number of consecutive blocks starting with Lba is
+ returned. All blocks in this range have a size of
+ BlockSize
+ Global - Pointer to ESAL_FWB_GLOBAL that contains all
+ instance data
+ Virtual - Whether CPU is in virtual or physical mode
+
+Returns:
+ EFI_SUCCESS - Successfully returns
+ EFI_INVALID_PARAMETER - Instance not found
+
+--*/
+{
+ UINT32 NumBlocks;
+ UINT32 BlockLength;
+ UINTN Offset;
+ EFI_LBA StartLba;
+ EFI_LBA NextLba;
+ EFI_FW_VOL_INSTANCE *FwhInstance;
+ EFI_FV_BLOCK_MAP_ENTRY *BlockMap;
+ EFI_STATUS Status;
+
+ FwhInstance = NULL;
+
+ //
+ // Find the right instance of the FVB private data
+ //
+ Status = GetFvbInstance (Instance, Global, &FwhInstance, Virtual);
+ ASSERT_EFI_ERROR (Status);
+
+ StartLba = 0;
+ Offset = 0;
+ BlockMap = &(FwhInstance->VolumeHeader.BlockMap[0]);
+
+ //
+ // Parse the blockmap of the FV to find which map entry the Lba belongs to
+ //
+ while (TRUE) {
+ NumBlocks = BlockMap->NumBlocks;
+ BlockLength = BlockMap->Length;
+
+ if ((NumBlocks == 0) || (BlockLength == 0)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ NextLba = StartLba + NumBlocks;
+
+ //
+ // The map entry found
+ //
+ if (Lba >= StartLba && Lba < NextLba) {
+ Offset = Offset + (UINTN) MultU64x32 ((Lba - StartLba), BlockLength);
+ if (LbaAddress) {
+ *LbaAddress = FwhInstance->FvBase[Virtual] + Offset;
+ }
+
+ if (LbaWriteAddress) {
+ *LbaWriteAddress = FwhInstance->FvWriteBase[Virtual] + Offset;
+ }
+
+ if (LbaLength) {
+ *LbaLength = BlockLength;
+ }
+
+ if (NumOfBlocks) {
+ *NumOfBlocks = (UINTN) (NextLba - Lba);
+ }
+
+ return EFI_SUCCESS;
+ }
+
+ StartLba = NextLba;
+ Offset = Offset + NumBlocks * BlockLength;
+ BlockMap++;
+ }
+}
+
+EFI_STATUS
+FvbReadBlock (
+ IN UINTN Instance,
+ IN EFI_LBA Lba,
+ IN UINTN BlockOffset,
+ IN OUT UINTN *NumBytes,
+ IN UINT8 *Buffer,
+ IN ESAL_FWB_GLOBAL *Global,
+ IN BOOLEAN Virtual
+ )
+/*++
+
+Routine Description:
+ Reads specified number of bytes into a buffer from the specified block
+
+Arguments:
+ Instance - The FV instance to be read from
+ Lba - The logical block address to be read from
+ BlockOffset - Offset into the block at which to begin reading
+ NumBytes - Pointer that on input contains the total size of
+ the buffer. On output, it contains the total number
+ of bytes read
+ Buffer - Pointer to a caller allocated buffer that will be
+ used to hold the data read
+ Global - Pointer to ESAL_FWB_GLOBAL that contains all
+ instance data
+ Virtual - Whether CPU is in virtual or physical mode
+
+Returns:
+ EFI_SUCCESS - The firmware volume was read successfully and
+ contents are in Buffer
+ EFI_BAD_BUFFER_SIZE - Read attempted across a LBA boundary. On output,
+ NumBytes contains the total number of bytes returned
+ in Buffer
+ EFI_ACCESS_DENIED - The firmware volume is in the ReadDisabled state
+ EFI_DEVICE_ERROR - The block device is not functioning correctly and
+ could not be read
+ EFI_INVALID_PARAMETER - Instance not found, or NumBytes, Buffer are NULL
+
+--*/
+{
+ EFI_FVB_ATTRIBUTES_2 Attributes;
+ UINTN LbaAddress;
+ UINTN LbaLength;
+ EFI_STATUS Status;
+
+ //
+ // Check for invalid conditions
+ //
+ if ((NumBytes == NULL) || (Buffer == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (*NumBytes == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = FvbGetLbaAddress (Instance, Lba, &LbaAddress, NULL, &LbaLength, NULL, Global, Virtual);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // Check if the FV is read enabled
+ //
+ FvbGetVolumeAttributes (Instance, &Attributes, Global, Virtual);
+
+ if ((Attributes & EFI_FVB2_READ_STATUS) == 0) {
+ return EFI_ACCESS_DENIED;
+ }
+ //
+ // Perform boundary checks and adjust NumBytes
+ //
+ if (BlockOffset > LbaLength) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (LbaLength < (*NumBytes + BlockOffset)) {
+ *NumBytes = (UINT32) (LbaLength - BlockOffset);
+ Status = EFI_BAD_BUFFER_SIZE;
+ }
+
+ MmioReadBuffer8 (LbaAddress + BlockOffset, (UINTN) *NumBytes, Buffer);
+
+ return Status;
+}
+
+EFI_STATUS
+FlashFdWrite (
+ IN UINTN WriteAddress,
+ IN UINTN Address,
+ IN OUT UINTN *NumBytes,
+ IN UINT8 *Buffer,
+ IN UINTN LbaLength
+ )
+/*++
+
+Routine Description:
+ Writes specified number of bytes from the input buffer to the address
+
+Arguments:
+
+Returns:
+
+--*/
+{
+ EFI_STATUS Status;
+
+ Status = EFI_SUCCESS;
+
+ //
+ // TODO: Suggested that this code be "critical section"
+ //
+ WriteAddress -= ( PcdGet32 (PcdFlashAreaBaseAddress) );
+ if (mInSmmMode == 0) { // !(EfiInManagementInterrupt ())) {
+ Status = mFvbModuleGlobal->SpiProtocol->Execute (
+ mFvbModuleGlobal->SpiProtocol,
+ SPI_OPCODE_WRITE_INDEX, // OpcodeIndex
+ 0, // PrefixOpcodeIndex
+ TRUE, // DataCycle
+ TRUE, // Atomic
+ TRUE, // ShiftOut
+ WriteAddress, // Address
+ (UINT32) (*NumBytes), // Data Number
+ Buffer,
+ EnumSpiRegionBios
+ );
+
+ } else {
+ Status = mFvbModuleGlobal->SmmSpiProtocol->Execute (
+ mFvbModuleGlobal->SmmSpiProtocol,
+ SPI_OPCODE_WRITE_INDEX, // OpcodeIndex
+ 0, // PrefixOpcodeIndex
+ TRUE, // DataCycle
+ TRUE, // Atomic
+ TRUE, // ShiftOut
+ WriteAddress, // Address
+ (UINT32) (*NumBytes), // Data Number
+ Buffer,
+ EnumSpiRegionBios
+ );
+ }
+
+ AsmWbinvd ();
+
+ return Status;
+}
+
+EFI_STATUS
+FlashFdErase (
+ IN UINTN WriteAddress,
+ IN UINTN Address,
+ IN UINTN LbaLength
+ )
+/*++
+
+Routine Description:
+ Erase a certain block from address LbaWriteAddress
+
+Arguments:
+
+Returns:
+
+--*/
+{
+ EFI_STATUS Status;
+ UINTN NumBytes;
+
+ NumBytes = LbaLength;
+
+ WriteAddress -= (PcdGet32 (PcdFlashAreaBaseAddress));
+ if (mInSmmMode == 0 ) { // !(EfiInManagementInterrupt ())) {
+ Status = mFvbModuleGlobal->SpiProtocol->Execute (
+ mFvbModuleGlobal->SpiProtocol,
+ SPI_OPCODE_ERASE_INDEX, // OpcodeIndex
+ 0, // PrefixOpcodeIndex
+ FALSE, // DataCycle
+ TRUE, // Atomic
+ FALSE, // ShiftOut
+ WriteAddress, // Address
+ 0, // Data Number
+ NULL,
+ EnumSpiRegionBios // SPI_REGION_TYPE
+ );
+ } else {
+ Status = mFvbModuleGlobal->SmmSpiProtocol->Execute (
+ mFvbModuleGlobal->SmmSpiProtocol,
+ SPI_OPCODE_ERASE_INDEX, // OpcodeIndex
+ 0, // PrefixOpcodeIndex
+ FALSE, // DataCycle
+ TRUE, // Atomic
+ FALSE, // ShiftOut
+ WriteAddress, // Address
+ 0, // Data Number
+ NULL,
+ EnumSpiRegionBios // SPI_REGION_TYPE
+ );
+ }
+
+ AsmWbinvd ();
+
+ return Status;
+}
+
+EFI_STATUS
+FvbWriteBlock (
+ IN UINTN Instance,
+ IN EFI_LBA Lba,
+ IN UINTN BlockOffset,
+ IN OUT UINTN *NumBytes,
+ IN UINT8 *Buffer,
+ IN ESAL_FWB_GLOBAL *Global,
+ IN BOOLEAN Virtual
+ )
+/*++
+
+Routine Description:
+ Writes specified number of bytes from the input buffer to the block
+
+Arguments:
+ Instance - The FV instance to be written to
+ Lba - The starting logical block index to write to
+ BlockOffset - Offset into the block at which to begin writing
+ NumBytes - Pointer that on input contains the total size of
+ the buffer. On output, it contains the total number
+ of bytes actually written
+ Buffer - Pointer to a caller allocated buffer that contains
+ the source for the write
+ Global - Pointer to ESAL_FWB_GLOBAL that contains all
+ instance data
+ Virtual - Whether CPU is in virtual or physical mode
+
+Returns:
+ EFI_SUCCESS - The firmware volume was written successfully
+ EFI_BAD_BUFFER_SIZE - Write attempted across a LBA boundary. On output,
+ NumBytes contains the total number of bytes
+ actually written
+ EFI_ACCESS_DENIED - The firmware volume is in the WriteDisabled state
+ EFI_DEVICE_ERROR - The block device is not functioning correctly and
+ could not be written
+ EFI_INVALID_PARAMETER - Instance not found, or NumBytes, Buffer are NULL
+
+--*/
+{
+ EFI_FVB_ATTRIBUTES_2 Attributes;
+ UINTN LbaAddress;
+ UINTN LbaWriteAddress;
+ UINTN LbaLength;
+ EFI_FW_VOL_INSTANCE *FwhInstance;
+ EFI_STATUS Status;
+ EFI_STATUS ReturnStatus;
+
+ FwhInstance = NULL;
+
+ //
+ // Find the right instance of the FVB private data
+ //
+ Status = GetFvbInstance (Instance, Global, &FwhInstance, Virtual);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Writes are enabled in the init routine itself
+ //
+ if (!FwhInstance->WriteEnabled) {
+ return EFI_ACCESS_DENIED;
+ }
+ //
+ // Check for invalid conditions
+ //
+ if ((NumBytes == NULL) || (Buffer == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (*NumBytes == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = FvbGetLbaAddress (Instance, Lba, &LbaAddress, &LbaWriteAddress, &LbaLength, NULL, Global, Virtual);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // Check if the FV is write enabled
+ //
+ FvbGetVolumeAttributes (Instance, &Attributes, Global, Virtual);
+
+ if ((Attributes & EFI_FVB2_WRITE_STATUS) == 0) {
+ return EFI_ACCESS_DENIED;
+ }
+ //
+ // Perform boundary checks and adjust NumBytes
+ //
+ if (BlockOffset > LbaLength) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (LbaLength < (*NumBytes + BlockOffset)) {
+ *NumBytes = (UINT32) (LbaLength - BlockOffset);
+ Status = EFI_BAD_BUFFER_SIZE;
+ }
+
+ ReturnStatus = FlashFdWrite (
+ LbaWriteAddress + BlockOffset,
+ LbaAddress,
+ NumBytes,
+ Buffer,
+ LbaLength
+ );
+ if (EFI_ERROR (ReturnStatus)) {
+ return ReturnStatus;
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+FvbEraseBlock (
+ IN UINTN Instance,
+ IN EFI_LBA Lba,
+ IN ESAL_FWB_GLOBAL *Global,
+ IN BOOLEAN Virtual
+ )
+/*++
+
+Routine Description:
+ Erases and initializes a firmware volume block
+
+Arguments:
+ Instance - The FV instance to be erased
+ Lba - The logical block index to be erased
+ Global - Pointer to ESAL_FWB_GLOBAL that contains all
+ instance data
+ Virtual - Whether CPU is in virtual or physical mode
+
+Returns:
+ EFI_SUCCESS - The erase request was successfully completed
+ EFI_ACCESS_DENIED - The firmware volume is in the WriteDisabled state
+ EFI_DEVICE_ERROR - The block device is not functioning correctly and
+ could not be written. Firmware device may have been
+ partially erased
+ EFI_INVALID_PARAMETER - Instance not found
+
+--*/
+{
+
+ EFI_FVB_ATTRIBUTES_2 Attributes;
+ UINTN LbaAddress;
+ UINTN LbaWriteAddress;
+ EFI_FW_VOL_INSTANCE *FwhInstance;
+ UINTN LbaLength;
+ EFI_STATUS Status;
+ UINTN SectorNum;
+ UINTN Index;
+
+ FwhInstance = NULL;
+
+ //
+ // Find the right instance of the FVB private data
+ //
+ Status = GetFvbInstance (Instance, Global, &FwhInstance, Virtual);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Writes are enabled in the init routine itself
+ //
+ if (!FwhInstance->WriteEnabled) {
+ return EFI_ACCESS_DENIED;
+ }
+ //
+ // Check if the FV is write enabled
+ //
+ FvbGetVolumeAttributes (Instance, &Attributes, Global, Virtual);
+
+ if ((Attributes & EFI_FVB2_WRITE_STATUS) == 0) {
+ return EFI_ACCESS_DENIED;
+ }
+ //
+ // Get the starting address of the block for erase. For debug reasons,
+ // LbaWriteAddress may not be the same as LbaAddress.
+ //
+ Status = FvbGetLbaAddress (Instance, Lba, &LbaAddress, &LbaWriteAddress, &LbaLength, NULL, Global, Virtual);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ SectorNum = LbaLength / SPI_ERASE_SECTOR_SIZE;
+ for (Index = 0; Index < SectorNum; Index++){
+ Status = FlashFdErase (
+ LbaWriteAddress + Index * SPI_ERASE_SECTOR_SIZE,
+ LbaAddress,
+ SPI_ERASE_SECTOR_SIZE
+ );
+ if (Status != EFI_SUCCESS){
+ break;
+ }
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+FvbEraseCustomBlockRange (
+ IN UINTN Instance,
+ IN EFI_LBA StartLba,
+ IN UINTN OffsetStartLba,
+ IN EFI_LBA LastLba,
+ IN UINTN OffsetLastLba,
+ IN ESAL_FWB_GLOBAL *Global,
+ IN BOOLEAN Virtual
+ )
+/*++
+
+Routine Description:
+ Erases and initializes a specified range of a firmware volume
+
+Arguments:
+ Instance - The FV instance to be erased
+ StartLba - The starting logical block index to be erased
+ OffsetStartLba - Offset into the starting block at which to
+ begin erasing
+ LastLba - The last logical block index to be erased
+ OffsetStartLba - Offset into the last block at which to end erasing
+ Global - Pointer to ESAL_FWB_GLOBAL that contains all
+ instance data
+ Virtual - Whether CPU is in virtual or physical mode
+
+Returns:
+ EFI_SUCCESS - The firmware volume was erased successfully
+ EFI_ACCESS_DENIED - The firmware volume is in the WriteDisabled state
+ EFI_DEVICE_ERROR - The block device is not functioning correctly and
+ could not be written. Firmware device may have been
+ partially erased
+ EFI_INVALID_PARAMETER - Instance not found
+
+--*/
+{
+ EFI_LBA Index;
+ UINTN LbaSize;
+ UINTN ScratchLbaSizeData;
+
+ //
+ // First LBA.
+ //
+ FvbGetLbaAddress (Instance, StartLba, NULL, NULL, &LbaSize, NULL, Global, Virtual);
+
+ //
+ // Use the scratch space as the intermediate buffer to transfer data
+ // Back up the first LBA in scratch space.
+ //
+ FvbReadBlock (Instance, StartLba, 0, &LbaSize, Global->FvbScratchSpace[Virtual], Global, Virtual);
+
+ //
+ // erase now
+ //
+ FvbEraseBlock (Instance, StartLba, Global, Virtual);
+ ScratchLbaSizeData = OffsetStartLba;
+
+ //
+ // write the data back to the first block
+ //
+ if (ScratchLbaSizeData > 0) {
+ FvbWriteBlock (Instance, StartLba, 0, &ScratchLbaSizeData, Global->FvbScratchSpace[Virtual], Global, Virtual);
+ }
+ //
+ // Middle LBAs
+ //
+ if (LastLba > (StartLba + 1)) {
+ for (Index = (StartLba + 1); Index <= (LastLba - 1); Index++) {
+ FvbEraseBlock (Instance, Index, Global, Virtual);
+ }
+ }
+ //
+ // Last LBAs, the same as first LBAs
+ //
+ if (LastLba > StartLba) {
+ FvbGetLbaAddress (Instance, LastLba, NULL, NULL, &LbaSize, NULL, Global, Virtual);
+ FvbReadBlock (Instance, LastLba, 0, &LbaSize, Global->FvbScratchSpace[Virtual], Global, Virtual);
+ FvbEraseBlock (Instance, LastLba, Global, Virtual);
+ }
+
+ ScratchLbaSizeData = LbaSize - (OffsetStartLba + 1);
+
+ return FvbWriteBlock (
+ Instance,
+ LastLba,
+ (OffsetLastLba + 1),
+ &ScratchLbaSizeData,
+ Global->FvbScratchSpace[Virtual],
+ Global,
+ Virtual
+ );
+}
+
+EFI_STATUS
+FvbSetVolumeAttributes (
+ IN UINTN Instance,
+ IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes,
+ IN ESAL_FWB_GLOBAL *Global,
+ IN BOOLEAN Virtual
+ )
+/*++
+
+Routine Description:
+ Modifies the current settings of the firmware volume according to the
+ input parameter, and returns the new setting of the volume
+
+Arguments:
+ Instance - The FV instance whose attributes is going to be
+ modified
+ Attributes - On input, it is a pointer to EFI_FVB_ATTRIBUTES_2
+ containing the desired firmware volume settings.
+ On successful return, it contains the new settings
+ of the firmware volume
+ Global - Pointer to ESAL_FWB_GLOBAL that contains all
+ instance data
+ Virtual - Whether CPU is in virtual or physical mode
+
+Returns:
+ EFI_SUCCESS - Successfully returns
+ EFI_ACCESS_DENIED - The volume setting is locked and cannot be modified
+ EFI_INVALID_PARAMETER - Instance not found, or The attributes requested are
+ in conflict with the capabilities as declared in the
+ firmware volume header
+
+--*/
+{
+ EFI_FW_VOL_INSTANCE *FwhInstance;
+ EFI_FVB_ATTRIBUTES_2 OldAttributes;
+ EFI_FVB_ATTRIBUTES_2 *AttribPtr;
+ UINT32 Capabilities;
+ UINT32 OldStatus;
+ UINT32 NewStatus;
+ EFI_STATUS Status;
+
+ FwhInstance = NULL;
+
+ //
+ // Find the right instance of the FVB private data
+ //
+ Status = GetFvbInstance (Instance, Global, &FwhInstance, Virtual);
+ ASSERT_EFI_ERROR (Status);
+
+ AttribPtr = (EFI_FVB_ATTRIBUTES_2 *) &(FwhInstance->VolumeHeader.Attributes);
+ OldAttributes = *AttribPtr;
+ Capabilities = OldAttributes & EFI_FVB2_CAPABILITIES;
+ OldStatus = OldAttributes & EFI_FVB2_STATUS;
+ NewStatus = *Attributes & EFI_FVB2_STATUS;
+
+ //
+ // If firmware volume is locked, no status bit can be updated
+ //
+ if (OldAttributes & EFI_FVB2_LOCK_STATUS) {
+ if (OldStatus ^ NewStatus) {
+ return EFI_ACCESS_DENIED;
+ }
+ }
+ //
+ // Test read disable
+ //
+ if ((Capabilities & EFI_FVB2_READ_DISABLED_CAP) == 0) {
+ if ((NewStatus & EFI_FVB2_READ_STATUS) == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+ //
+ // Test read enable
+ //
+ if ((Capabilities & EFI_FVB2_READ_ENABLED_CAP) == 0) {
+ if (NewStatus & EFI_FVB2_READ_STATUS) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+ //
+ // Test write disable
+ //
+ if ((Capabilities & EFI_FVB2_WRITE_DISABLED_CAP) == 0) {
+ if ((NewStatus & EFI_FVB2_WRITE_STATUS) == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+ //
+ // Test write enable
+ //
+ if ((Capabilities & EFI_FVB2_WRITE_ENABLED_CAP) == 0) {
+ if (NewStatus & EFI_FVB2_WRITE_STATUS) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+ //
+ // Test lock
+ //
+ if ((Capabilities & EFI_FVB2_LOCK_CAP) == 0) {
+ if (NewStatus & EFI_FVB2_LOCK_STATUS) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ *AttribPtr = (*AttribPtr) & (0xFFFFFFFF & (~EFI_FVB2_STATUS));
+ *AttribPtr = (*AttribPtr) | NewStatus;
+ *Attributes = *AttribPtr;
+
+ return EFI_SUCCESS;
+}
+//
+// FVB protocol APIs
+//
+EFI_STATUS
+EFIAPI
+FvbProtocolGetPhysicalAddress (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ OUT EFI_PHYSICAL_ADDRESS *Address
+ )
+/*++
+
+Routine Description:
+
+ Retrieves the physical address of the device.
+
+Arguments:
+
+ This - Calling context
+ Address - Output buffer containing the address.
+
+Returns:
+
+Returns:
+ EFI_SUCCESS - Successfully returns
+
+--*/
+{
+ EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
+
+ FvbDevice = FVB_DEVICE_FROM_THIS (This);
+
+ return FvbGetPhysicalAddress (FvbDevice->Instance, Address, mFvbModuleGlobal, EfiGoneVirtual ());
+}
+
+EFI_STATUS
+FvbProtocolGetBlockSize (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ IN EFI_LBA Lba,
+ OUT UINTN *BlockSize,
+ OUT UINTN *NumOfBlocks
+ )
+/*++
+
+Routine Description:
+ Retrieve the size of a logical block
+
+Arguments:
+ This - Calling context
+ Lba - Indicates which block to return the size for.
+ BlockSize - A pointer to a caller allocated UINTN in which
+ the size of the block is returned
+ NumOfBlocks - a pointer to a caller allocated UINTN in which the
+ number of consecutive blocks starting with Lba is
+ returned. All blocks in this range have a size of
+ BlockSize
+
+Returns:
+ EFI_SUCCESS - The firmware volume was read successfully and
+ contents are in Buffer
+
+--*/
+{
+ EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
+
+ FvbDevice = FVB_DEVICE_FROM_THIS (This);
+
+ return FvbGetLbaAddress (
+ FvbDevice->Instance,
+ Lba,
+ NULL,
+ NULL,
+ BlockSize,
+ NumOfBlocks,
+ mFvbModuleGlobal,
+ EfiGoneVirtual ()
+ );
+}
+
+EFI_STATUS
+EFIAPI
+FvbProtocolGetAttributes (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ OUT EFI_FVB_ATTRIBUTES_2 *Attributes
+ )
+/*++
+
+Routine Description:
+ Retrieves Volume attributes. No polarity translations are done.
+
+Arguments:
+ This - Calling context
+ Attributes - output buffer which contains attributes
+
+Returns:
+ EFI_SUCCESS - Successfully returns
+
+--*/
+{
+ EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
+
+ FvbDevice = FVB_DEVICE_FROM_THIS (This);
+
+ return FvbGetVolumeAttributes (FvbDevice->Instance, Attributes, mFvbModuleGlobal, EfiGoneVirtual ());
+}
+
+EFI_STATUS
+EFIAPI
+FvbProtocolSetAttributes (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes
+ )
+/*++
+
+Routine Description:
+ Sets Volume attributes. No polarity translations are done.
+
+Arguments:
+ This - Calling context
+ Attributes - output buffer which contains attributes
+
+Returns:
+ EFI_SUCCESS - Successfully returns
+
+--*/
+{
+ EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
+
+ FvbDevice = FVB_DEVICE_FROM_THIS (This);
+
+ return FvbSetVolumeAttributes (FvbDevice->Instance, Attributes, mFvbModuleGlobal, EfiGoneVirtual ());
+}
+
+EFI_STATUS
+EFIAPI
+FvbProtocolEraseBlocks (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ ...
+ )
+/*++
+
+Routine Description:
+
+ The EraseBlock() function erases one or more blocks as denoted by the
+ variable argument list. The entire parameter list of blocks must be verified
+ prior to erasing any blocks. If a block is requested that does not exist
+ within the associated firmware volume (it has a larger index than the last
+ block of the firmware volume), the EraseBlock() function must return
+ EFI_INVALID_PARAMETER without modifying the contents of the firmware volume.
+
+Arguments:
+ This - Calling context
+ ... - Starting LBA followed by Number of Lba to erase.
+ a -1 to terminate the list.
+
+Returns:
+ EFI_SUCCESS - The erase request was successfully completed
+ EFI_ACCESS_DENIED - The firmware volume is in the WriteDisabled state
+ EFI_DEVICE_ERROR - The block device is not functioning correctly and
+ could not be written. Firmware device may have been
+ partially erased
+
+--*/
+{
+ EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
+ EFI_FW_VOL_INSTANCE *FwhInstance;
+ UINTN NumOfBlocks;
+ VA_LIST args;
+ EFI_LBA StartingLba;
+ UINTN NumOfLba;
+ EFI_STATUS Status;
+
+ FwhInstance = NULL;
+ FvbDevice = FVB_DEVICE_FROM_THIS (This);
+
+ Status = GetFvbInstance (FvbDevice->Instance, mFvbModuleGlobal, &FwhInstance, EfiGoneVirtual ());
+ ASSERT_EFI_ERROR (Status);
+
+ NumOfBlocks = FwhInstance->NumOfBlocks;
+
+ VA_START (args, This);
+
+ do {
+ StartingLba = VA_ARG (args, EFI_LBA);
+ if (StartingLba == EFI_LBA_LIST_TERMINATOR) {
+ break;
+ }
+
+ NumOfLba = VA_ARG (args, UINT32);
+
+ //
+ // Check input parameters
+ //
+ if (NumOfLba == 0) {
+ VA_END (args);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((StartingLba + NumOfLba) > NumOfBlocks) {
+ return EFI_INVALID_PARAMETER;
+ }
+ } while (TRUE);
+
+ VA_END (args);
+
+ VA_START (args, This);
+ do {
+ StartingLba = VA_ARG (args, EFI_LBA);
+ if (StartingLba == EFI_LBA_LIST_TERMINATOR) {
+ break;
+ }
+
+ NumOfLba = VA_ARG (args, UINT32);
+
+ while (NumOfLba > 0) {
+ Status = FvbEraseBlock (FvbDevice->Instance, StartingLba, mFvbModuleGlobal, EfiGoneVirtual ());
+ if (EFI_ERROR (Status)) {
+ VA_END (args);
+ return Status;
+ }
+
+ StartingLba++;
+ NumOfLba--;
+ }
+
+ } while (TRUE);
+
+ VA_END (args);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+FvbProtocolWrite (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ IN EFI_LBA Lba,
+ IN UINTN Offset,
+ IN OUT UINTN *NumBytes,
+ IN UINT8 *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Writes data beginning at Lba:Offset from FV. The write terminates either
+ when *NumBytes of data have been written, or when a block boundary is
+ reached. *NumBytes is updated to reflect the actual number of bytes
+ written. The write opertion does not include erase. This routine will
+ attempt to write only the specified bytes. If the writes do not stick,
+ it will return an error.
+
+Arguments:
+ This - Calling context
+ Lba - Block in which to begin write
+ Offset - Offset in the block at which to begin write
+ NumBytes - On input, indicates the requested write size. On
+ output, indicates the actual number of bytes written
+ Buffer - Buffer containing source data for the write.
+
+Returns:
+ EFI_SUCCESS - The firmware volume was written successfully
+ EFI_BAD_BUFFER_SIZE - Write attempted across a LBA boundary. On output,
+ NumBytes contains the total number of bytes
+ actually written
+ EFI_ACCESS_DENIED - The firmware volume is in the WriteDisabled state
+ EFI_DEVICE_ERROR - The block device is not functioning correctly and
+ could not be written
+ EFI_INVALID_PARAMETER - NumBytes or Buffer are NULL
+
+--*/
+{
+
+ EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
+
+ FvbDevice = FVB_DEVICE_FROM_THIS (This);
+
+ return FvbWriteBlock (FvbDevice->Instance, Lba, Offset, NumBytes, Buffer, mFvbModuleGlobal, EfiGoneVirtual ());
+}
+
+EFI_STATUS
+EFIAPI
+FvbProtocolRead (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ IN EFI_LBA Lba,
+ IN UINTN Offset,
+ IN OUT UINTN *NumBytes,
+ IN UINT8 *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Reads data beginning at Lba:Offset from FV. The Read terminates either
+ when *NumBytes of data have been read, or when a block boundary is
+ reached. *NumBytes is updated to reflect the actual number of bytes
+ written. The write opertion does not include erase. This routine will
+ attempt to write only the specified bytes. If the writes do not stick,
+ it will return an error.
+
+Arguments:
+ This - Calling context
+ Lba - Block in which to begin Read
+ Offset - Offset in the block at which to begin Read
+ NumBytes - On input, indicates the requested write size. On
+ output, indicates the actual number of bytes Read
+ Buffer - Buffer containing source data for the Read.
+
+Returns:
+ EFI_SUCCESS - The firmware volume was read successfully and
+ contents are in Buffer
+ EFI_BAD_BUFFER_SIZE - Read attempted across a LBA boundary. On output,
+ NumBytes contains the total number of bytes returned
+ in Buffer
+ EFI_ACCESS_DENIED - The firmware volume is in the ReadDisabled state
+ EFI_DEVICE_ERROR - The block device is not functioning correctly and
+ could not be read
+ EFI_INVALID_PARAMETER - NumBytes or Buffer are NULL
+
+--*/
+{
+
+ EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
+ EFI_STATUS Status;
+
+ FvbDevice = FVB_DEVICE_FROM_THIS (This);
+ Status = FvbReadBlock (FvbDevice->Instance, Lba, Offset, NumBytes, Buffer, mFvbModuleGlobal, EfiGoneVirtual ());
+
+ return Status;
+}
+
+EFI_STATUS
+ValidateFvHeader (
+ EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader
+ )
+/*++
+
+Routine Description:
+ Check the integrity of firmware volume header
+
+Arguments:
+ FwVolHeader - A pointer to a firmware volume header
+
+Returns:
+ EFI_SUCCESS - The firmware volume is consistent
+ EFI_NOT_FOUND - The firmware volume has corrupted. So it is not an FV
+
+--*/
+{
+ UINT16 *Ptr;
+ UINT16 HeaderLength;
+ UINT16 Checksum;
+
+ //
+ // Verify the header revision, header signature, length
+ // Length of FvBlock cannot be 2**64-1
+ // HeaderLength cannot be an odd number
+ //
+ #ifndef R864_BUILD
+ if (((FwVolHeader->Revision != EFI_FVH_REVISION) && (FwVolHeader->Revision != EFI_FVH_REVISION)) ||
+ #else
+ if ((FwVolHeader->Revision != EFI_FVH_REVISION) ||
+ #endif
+ (FwVolHeader->Signature != EFI_FVH_SIGNATURE) ||
+ (FwVolHeader->FvLength == ((UINTN) -1)) ||
+ ((FwVolHeader->HeaderLength & 0x01) != 0)
+ ) {
+ return EFI_NOT_FOUND;
+ }
+ //
+ // Verify the header checksum
+ //
+ HeaderLength = (UINT16) (FwVolHeader->HeaderLength / 2);
+ Ptr = (UINT16 *) FwVolHeader;
+ Checksum = 0;
+ while (HeaderLength > 0) {
+ Checksum = Checksum + (*Ptr);
+ Ptr++;
+ HeaderLength--;
+ }
+
+ if (Checksum != 0) {
+ return EFI_NOT_FOUND;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+GetFvbHeader (
+ VOID **HobList,
+ OUT EFI_FIRMWARE_VOLUME_HEADER **FwVolHeader,
+ OUT EFI_PHYSICAL_ADDRESS *BaseAddress,
+ OUT BOOLEAN *WriteBack
+ )
+{
+ EFI_STATUS Status;
+
+ Status = EFI_SUCCESS;
+ *WriteBack = FALSE;
+
+ if (*FwVolHeader == NULL) {
+ *BaseAddress = PcdGet32 (PcdFlashFvRecoveryBase);
+ } else if (*FwVolHeader == (VOID *)(UINTN)PcdGet32 (PcdFlashFvRecoveryBase)) {
+ *BaseAddress = PcdGet32 (PcdFlashFvMainBase);
+ } else if (*FwVolHeader == (VOID *)(UINTN)PcdGet32 (PcdFlashFvMainBase)) {
+ *BaseAddress = PcdGet32 (PcdFlashNvStorageVariableBase);
+ } else {
+ return EFI_NOT_FOUND;
+ }
+
+ DEBUG((EFI_D_INFO, "Fvb base : %08x\n",*BaseAddress));
+
+ *FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) (*BaseAddress);
+ Status = ValidateFvHeader (*FwVolHeader);
+ if (EFI_ERROR (Status)) {
+ //
+ // Get FvbInfo
+ //
+ *WriteBack = TRUE;
+
+ Status = GetFvbInfo (*BaseAddress, FwVolHeader);
+ DEBUG(( DEBUG_ERROR, "Through GetFvbInfo: %08x!\n",*BaseAddress));
+
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+SmmSpiInit (
+ VOID
+ )
+{
+ UINT8 SpiStatus;
+ UINT8 FlashIndex;
+ UINT8 FlashID[3];
+ EFI_STATUS Status;
+
+ //
+ // Obtain a handle for ICH SPI Protocol
+ //
+ ASSERT(mSmst != NULL);
+ if (mFvbModuleGlobal->SmmSpiProtocol == NULL){
+ Status = mSmst->SmmLocateProtocol (&gEfiSmmSpiProtocolGuid, NULL, (VOID **) &mFvbModuleGlobal->SmmSpiProtocol);
+ ASSERT_EFI_ERROR(Status);
+ }
+ //
+ // attempt to identify flash part and initialize spi table
+ //
+ for (FlashIndex = 0; FlashIndex < EnumSpiFlashMax; FlashIndex++) {
+ Status = mFvbModuleGlobal->SmmSpiProtocol->Init (
+ mFvbModuleGlobal->SmmSpiProtocol,
+ &(mSpiInitTable[FlashIndex])
+ );
+ if (!EFI_ERROR (Status)) {
+ //
+ // read vendor/device IDs to check if flash device is supported
+ //
+ Status = mFvbModuleGlobal->SmmSpiProtocol->Execute (
+ mFvbModuleGlobal->SmmSpiProtocol,
+ SPI_OPCODE_JEDEC_ID_INDEX,
+ SPI_WREN_INDEX,
+ TRUE,
+ FALSE,
+ FALSE,
+ 0,
+ 3,
+ FlashID,
+ EnumSpiRegionAll
+ );
+ if (!EFI_ERROR (Status)) {
+ if (((FlashID[0] == mSpiInitTable[FlashIndex].VendorId) &&
+ (FlashID[2] == mSpiInitTable[FlashIndex].DeviceId1)) ||
+ ((FlashID[0] == SPI_AT26DF321_ID1) &&
+ (FlashID[0] == mSpiInitTable[FlashIndex].VendorId) &&
+ (FlashID[1] == mSpiInitTable[FlashIndex].DeviceId0))) {
+ //
+ // Supported SPI device found
+ //
+ DEBUG (
+ ((EFI_D_INFO),
+ "Smm Mode: Supported SPI Flash device found, Vendor Id: 0x%02x, Device ID: 0x%02x%02x!\n",
+ FlashID[0],
+ FlashID[1],
+ FlashID[2])
+ );
+ break;
+ }
+ }
+ }
+ }
+
+ if (FlashIndex >= EnumSpiFlashMax) {
+ Status = EFI_UNSUPPORTED;
+ DEBUG (
+ (EFI_D_ERROR,
+ "ERROR - Unknown SPI Flash Device, Vendor Id: 0x%02x, Device ID: 0x%02x%02x!\n",
+ FlashID[0],
+ FlashID[1],
+ FlashID[2])
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ SpiStatus = 0;
+ Status = mFvbModuleGlobal->SmmSpiProtocol->Execute (
+ mFvbModuleGlobal->SmmSpiProtocol,
+ SPI_OPCODE_WRITE_S_INDEX, // OpcodeIndex
+ 1, // PrefixOpcodeIndex
+ TRUE, // DataCycle
+ TRUE, // Atomic
+ TRUE, // ShiftOut
+ 0, // Address
+ 1, // Data Number
+ &SpiStatus,
+ EnumSpiRegionAll // SPI_REGION_TYPE
+ );
+ return Status;
+}
+
+EFI_STATUS
+SmmSpiNotificationFunction (
+ IN CONST EFI_GUID *Protocol,
+ IN VOID *Interface,
+ IN EFI_HANDLE Handle
+ )
+{
+ return SmmSpiInit();
+}
+
+
+VOID
+EFIAPI
+GetFullDriverPath (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable,
+ OUT EFI_DEVICE_PATH_PROTOCOL **CompleteFilePath
+ )
+/*++
+
+Routine Description:
+
+ Function is used to get the full device path for this driver.
+
+Arguments:
+
+ ImageHandle - The loaded image handle of this driver.
+ SystemTable - The pointer of system table.
+ CompleteFilePath - The pointer of returned full file path
+
+Returns:
+
+ none
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
+ EFI_DEVICE_PATH_PROTOCOL *ImageDevicePath;
+
+
+ Status = gBS->HandleProtocol (
+ ImageHandle,
+ &gEfiLoadedImageProtocolGuid,
+ (VOID **) &LoadedImage
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = gBS->HandleProtocol (
+ LoadedImage->DeviceHandle,
+ &gEfiDevicePathProtocolGuid,
+ (VOID *) &ImageDevicePath
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ *CompleteFilePath = AppendDevicePath (
+ ImageDevicePath,
+ LoadedImage->FilePath
+ );
+
+ return ;
+}
+
+
+
+EFI_STATUS
+FvbInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+/*++
+
+Routine Description:
+ This function does common initialization for FVB services
+
+Arguments:
+
+Returns:
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_FW_VOL_INSTANCE *FwhInstance;
+ EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
+ EFI_FIRMWARE_VOLUME_HEADER *TempFwVolHeader;
+ VOID *HobList;
+ VOID *FirmwareVolumeHobList;
+ UINT32 BufferSize;
+ EFI_FV_BLOCK_MAP_ENTRY *PtrBlockMapEntry;
+ UINTN LbaAddress;
+ BOOLEAN WriteEnabled;
+ BOOLEAN WriteLocked;
+ EFI_HANDLE FwbHandle;
+ EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
+ EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *OldFwbInterface;
+ EFI_DEVICE_PATH_PROTOCOL *FwbDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *TempFwbDevicePath;
+ UINT32 MaxLbaSize;
+ EFI_PHYSICAL_ADDRESS BaseAddress;
+ BOOLEAN WriteBack;
+ UINTN NumOfBlocks;
+ UINTN HeaderLength;
+ UINT8 SpiStatus;
+ UINT8 FlashIndex;
+ UINT8 FlashID[3];
+ EFI_DEVICE_PATH_PROTOCOL *CompleteFilePath;
+ UINT8 PrefixOpcodeIndex;
+ BOOLEAN InSmm;
+ EFI_SMM_BASE2_PROTOCOL *mSmmBase2;
+ EFI_HANDLE Handle;
+
+ VOID *Registration;
+ EFI_EVENT Event;
+
+ CompleteFilePath = NULL;
+ GetFullDriverPath (ImageHandle, SystemTable, &CompleteFilePath);
+
+ Status = EfiGetSystemConfigurationTable (&gEfiHobListGuid, &HobList);
+
+ //
+ // No FV HOBs found
+ //
+ ASSERT_EFI_ERROR (Status);
+
+
+ //
+ // Allocate runtime services data for global variable, which contains
+ // the private data of all firmware volume block instances
+ //
+ mFvbModuleGlobal = (ESAL_FWB_GLOBAL *)AllocateRuntimeZeroPool(sizeof (ESAL_FWB_GLOBAL ));
+ ASSERT(mFvbModuleGlobal);
+ mSmmBase2 = NULL;
+ Status = gBS->LocateProtocol (
+ &gEfiSmmBase2ProtocolGuid,
+ NULL,
+ (VOID **) &mSmmBase2
+ );
+
+ if (mSmmBase2 == NULL) {
+ InSmm = FALSE;
+ } else {
+ mSmmBase2->InSmm (mSmmBase2, &InSmm);
+ mSmmBase2->GetSmstLocation (mSmmBase2, &mSmst);
+
+ }
+
+ if (!InSmm) {
+ mInSmmMode = 0;
+ //
+ // Obtain a handle for ICH SPI Protocol
+ //
+ Status = gBS->LocateProtocol (&gEfiSpiProtocolGuid, NULL, (VOID **) &mFvbModuleGlobal->SpiProtocol);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // attempt to identify flash part and initialize spi table
+ //
+ for (FlashIndex = 0; FlashIndex < EnumSpiFlashMax; FlashIndex++) {
+ Status = mFvbModuleGlobal->SpiProtocol->Init (
+ mFvbModuleGlobal->SpiProtocol,
+ &(mSpiInitTable[FlashIndex])
+ );
+ if (!EFI_ERROR (Status)) {
+ //
+ // read vendor/device IDs to check if flash device is supported
+ //
+ Status = mFvbModuleGlobal->SpiProtocol->Execute (
+ mFvbModuleGlobal->SpiProtocol,
+ SPI_OPCODE_JEDEC_ID_INDEX,
+ SPI_WREN_INDEX,
+ TRUE,
+ FALSE,
+ FALSE,
+ 0,
+ 3,
+ FlashID,
+ EnumSpiRegionAll
+ );
+ if (!EFI_ERROR (Status)) {
+ if (((FlashID[0] == mSpiInitTable[FlashIndex].VendorId) &&
+ (FlashID[2] == mSpiInitTable[FlashIndex].DeviceId1)) ||
+ ((FlashID[0] == SPI_AT26DF321_ID1) &&
+ (FlashID[0] == mSpiInitTable[FlashIndex].VendorId) &&
+ (FlashID[1] == mSpiInitTable[FlashIndex].DeviceId0))) {
+ //
+ // Supported SPI device found
+ //
+ DEBUG (
+ ((EFI_D_INFO),
+ "Supported SPI Flash device found, Vendor Id: 0x%02x, Device ID: 0x%02x%02x!\n",
+ FlashID[0],
+ FlashID[1],
+ FlashID[2])
+ );
+
+ PublishFlashDeviceInfo (&mSpiInitTable[FlashIndex]);
+ break;
+ }
+ }
+ }
+ }
+
+ if (FlashIndex >= EnumSpiFlashMax) {
+ Status = EFI_UNSUPPORTED;
+ DEBUG (
+ (DEBUG_ERROR,
+ "ERROR - Unknown SPI Flash Device, Vendor Id: 0x%02x, Device ID: 0x%02x%02x!\n",
+ FlashID[0],
+ FlashID[1],
+ FlashID[2])
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ //
+ // Unlock all regions by writing to status register
+ // This could be SPI device specific, need to follow the datasheet
+ // To write to Write Status Register the Spi PrefixOpcode needs to be:
+ // 0 for Atmel parts
+ // 0 for Intel parts
+ // 0 for Macronix parts
+ // 0 for Winbond parts
+ // 1 for SST parts
+ SpiStatus = 0;
+ if (FlashID[0] == SPI_SST25VF016B_ID1) {
+ PrefixOpcodeIndex = 1;
+ } else {
+ PrefixOpcodeIndex = 0;
+ }
+ Status = mFvbModuleGlobal->SpiProtocol->Execute (
+ mFvbModuleGlobal->SpiProtocol,
+ SPI_OPCODE_WRITE_S_INDEX, // OpcodeIndex
+ PrefixOpcodeIndex, // PrefixOpcodeIndex
+ TRUE, // DataCycle
+ TRUE, // Atomic
+ TRUE, // ShiftOut
+ 0, // Address
+ 1, // Data Number
+ &SpiStatus,
+ EnumSpiRegionAll // SPI_REGION_TYPE
+ );
+
+
+ } else {
+ mInSmmMode = 1;
+
+ Status = mSmst->SmmLocateProtocol (&gEfiSmmSpiProtocolGuid, NULL, (VOID **) &mFvbModuleGlobal->SmmSpiProtocol);
+ if (EFI_ERROR(Status)) {
+ Registration = NULL;
+ Status = mSmst->SmmRegisterProtocolNotify (
+ &gEfiSmmSpiProtocolGuid,
+ SmmSpiNotificationFunction,
+ &Registration
+ );
+ } else {
+ Status = SmmSpiInit();
+ }
+
+ }
+
+ //
+ // Calculate the total size for all firmware volume block instances
+ //
+ BufferSize = 0;
+ FirmwareVolumeHobList = HobList;
+ FwVolHeader = NULL;
+ do {
+ Status = GetFvbHeader (&FirmwareVolumeHobList, &FwVolHeader, &BaseAddress, &WriteBack);
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+
+ if (FwVolHeader) {
+ BufferSize += (FwVolHeader->HeaderLength + sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER));
+ }
+ } while (TRUE);
+
+ //
+ // Only need to allocate once. There is only one copy of physical memory for
+ // the private data of each FV instance. But in virtual mode or in physical
+ // mode, the address of the the physical memory may be different.
+ //
+ mFvbModuleGlobal->FvInstance[FVB_PHYSICAL] = (EFI_FW_VOL_INSTANCE *) AllocateRuntimeZeroPool (BufferSize);
+ ASSERT(mFvbModuleGlobal->FvInstance[FVB_PHYSICAL]);
+ //
+ // Make a virtual copy of the FvInstance pointer.
+ //
+ FwhInstance = mFvbModuleGlobal->FvInstance[FVB_PHYSICAL];
+ mFvbModuleGlobal->FvInstance[FVB_VIRTUAL] = FwhInstance;
+
+ mFvbModuleGlobal->NumFv = 0;
+ FirmwareVolumeHobList = HobList;
+ TempFwVolHeader = NULL;
+
+ MaxLbaSize = 0;
+
+ //
+ // Fill in the private data of each firmware volume block instance
+ //
+ // Foreach Fv HOB in the FirmwareVolumeHobList, loop
+ //
+ do {
+ Status = GetFvbHeader (&FirmwareVolumeHobList, &TempFwVolHeader, &BaseAddress, &WriteBack);
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+ FwVolHeader = TempFwVolHeader;
+
+ if (!FwVolHeader) {
+ continue;
+ }
+
+
+ CopyMem ((UINTN *) &(FwhInstance->VolumeHeader), (UINTN *) FwVolHeader, FwVolHeader->HeaderLength);
+ FwVolHeader = &(FwhInstance->VolumeHeader);
+
+ FwhInstance->FvBase[FVB_PHYSICAL] = (UINTN) BaseAddress;
+ FwhInstance->FvBase[FVB_VIRTUAL] = (UINTN) BaseAddress;
+
+ //
+ // FwhInstance->FvWriteBase may not be the same as FwhInstance->FvBase
+ //
+ FwhInstance->FvWriteBase[FVB_PHYSICAL] = (UINTN) BaseAddress;
+ WriteEnabled = TRUE;
+
+ //
+ // Every pointer should have a virtual copy.
+ //
+ FwhInstance->FvWriteBase[FVB_VIRTUAL] = FwhInstance->FvWriteBase[FVB_PHYSICAL];
+
+ FwhInstance->WriteEnabled = WriteEnabled;
+ EfiInitializeLock (&(FwhInstance->FvbDevLock), TPL_HIGH_LEVEL);
+
+ LbaAddress = (UINTN) FwhInstance->FvWriteBase[0];
+ NumOfBlocks = 0;
+ WriteLocked = FALSE;
+
+ if (WriteEnabled) {
+ for (PtrBlockMapEntry = FwVolHeader->BlockMap; PtrBlockMapEntry->NumBlocks != 0; PtrBlockMapEntry++) {
+ //
+ // Get the maximum size of a block. The size will be used to allocate
+ // buffer for Scratch space, the intermediate buffer for FVB extension
+ // protocol
+ //
+ if (MaxLbaSize < PtrBlockMapEntry->Length) {
+ MaxLbaSize = PtrBlockMapEntry->Length;
+ }
+
+ NumOfBlocks = NumOfBlocks + PtrBlockMapEntry->NumBlocks;
+ }
+ //
+ // Write back a healthy FV header
+ //
+ if (WriteBack && (!WriteLocked)) {
+
+ Status = FlashFdErase (
+ (UINTN) FwhInstance->FvWriteBase[0],
+ (UINTN) BaseAddress,
+ FwVolHeader->BlockMap->Length
+ );
+
+ HeaderLength = (UINTN) FwVolHeader->HeaderLength;
+ Status = FlashFdWrite (
+ (UINTN) FwhInstance->FvWriteBase[0],
+ (UINTN) BaseAddress,
+ &HeaderLength,
+ (UINT8 *) FwVolHeader,
+ FwVolHeader->BlockMap->Length
+ );
+
+ }
+ }
+ //
+ // The total number of blocks in the FV.
+ //
+ FwhInstance->NumOfBlocks = NumOfBlocks;
+
+ //
+ // If the FV is write locked, set the appropriate attributes
+ //
+ if (WriteLocked) {
+ //
+ // write disabled
+ //
+ FwhInstance->VolumeHeader.Attributes &= ~EFI_FVB2_WRITE_STATUS;
+ //
+ // lock enabled
+ //
+ FwhInstance->VolumeHeader.Attributes |= EFI_FVB2_LOCK_STATUS;
+ }
+
+ //
+ // Allocate and initialize FVB Device in a runtime data buffer
+ //
+ FvbDevice = AllocateRuntimeCopyPool (sizeof (EFI_FW_VOL_BLOCK_DEVICE), &mFvbDeviceTemplate);
+ ASSERT (FvbDevice);
+
+ FvbDevice->Instance = mFvbModuleGlobal->NumFv;
+ mFvbModuleGlobal->NumFv++;
+
+ //
+ // FV does not contains extension header, then produce MEMMAP_DEVICE_PATH
+ //
+ if (FwVolHeader->ExtHeaderOffset == 0) {
+ FvbDevice->FvDevicePath.MemMapDevPath.StartingAddress = BaseAddress;
+ FvbDevice->FvDevicePath.MemMapDevPath.EndingAddress = BaseAddress + (FwVolHeader->FvLength - 1);
+ FwbDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)&FvbDevice->FvDevicePath;
+ } else {
+ CopyGuid (
+ &FvbDevice->UefiFvDevicePath.FvDevPath.FvName,
+ (EFI_GUID *)(UINTN)(BaseAddress + FwVolHeader->ExtHeaderOffset)
+ );
+ FwbDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)&FvbDevice->UefiFvDevicePath;
+ }
+
+ if (!InSmm) {
+ //
+ // Find a handle with a matching device path that has supports FW Block protocol
+ //
+ TempFwbDevicePath = FwbDevicePath;
+ Status = gBS->LocateDevicePath (&gEfiFirmwareVolumeBlockProtocolGuid, &TempFwbDevicePath, &FwbHandle);
+ if (EFI_ERROR (Status)) {
+ //
+ // LocateDevicePath fails so install a new interface and device path
+ //
+ FwbHandle = NULL;
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &FwbHandle,
+ &gEfiFirmwareVolumeBlockProtocolGuid,
+ &FvbDevice->FwVolBlockInstance,
+ &gEfiDevicePathProtocolGuid,
+ FwbDevicePath,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+ } else if (EfiIsDevicePathEnd (TempFwbDevicePath)) {
+ //
+ // Device already exists, so reinstall the FVB protocol
+ //
+ Status = gBS->HandleProtocol (
+ FwbHandle,
+ &gEfiFirmwareVolumeBlockProtocolGuid,
+ (VOID **) &OldFwbInterface
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = gBS->ReinstallProtocolInterface (
+ FwbHandle,
+ &gEfiFirmwareVolumeBlockProtocolGuid,
+ OldFwbInterface,
+ &FvbDevice->FwVolBlockInstance
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ } else {
+ //
+ // There was a FVB protocol on an End Device Path node
+ //
+ ASSERT (FALSE);
+ }
+ } else {
+ FwbHandle = NULL;
+ Status = mSmst->SmmInstallProtocolInterface (
+ &FwbHandle,
+ &gEfiSmmFirmwareVolumeBlockProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &FvbDevice->FwVolBlockInstance
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ FwhInstance = (EFI_FW_VOL_INSTANCE *)
+ (
+ (UINTN) ((UINT8 *) FwhInstance) + FwVolHeader->HeaderLength +
+ (sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER))
+ );
+ } while (TRUE);
+
+ //
+ // Allocate for scratch space, an intermediate buffer for FVB extention
+ //
+
+ mFvbModuleGlobal->FvbScratchSpace[FVB_PHYSICAL] = AllocateRuntimeZeroPool (MaxLbaSize);
+
+ ASSERT (mFvbModuleGlobal->FvbScratchSpace[FVB_PHYSICAL]);
+
+ mFvbModuleGlobal->FvbScratchSpace[FVB_VIRTUAL] = mFvbModuleGlobal->FvbScratchSpace[FVB_PHYSICAL];
+
+ if (!InSmm) {
+ Status = gBS->CreateEventEx (
+ EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ FvbVirtualddressChangeEvent,
+ NULL,
+ &gEfiEventVirtualAddressChangeGuid,
+ &Event
+ );
+ ASSERT_EFI_ERROR (Status);
+ } else {
+ //
+ // Inform other platform drivers that SPI device discovered and
+ // SPI interface ready for use.
+ //
+ Handle = NULL;
+ Status = gBS->InstallProtocolInterface (
+ &Handle,
+ &gEfiSmmSpiReadyProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ NULL
+ );
+ }
+ return EFI_SUCCESS;
+}
diff --git a/QuarkPlatformPkg/Platform/SpiFvbServices/FwBlockService.h b/QuarkPlatformPkg/Platform/SpiFvbServices/FwBlockService.h
new file mode 100644
index 0000000000..03ed426439
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/SpiFvbServices/FwBlockService.h
@@ -0,0 +1,314 @@
+/** @file
+Firmware volume block driver for SPI device
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+
+**/
+
+#ifndef _FW_BLOCK_SERVICE_H
+#define _FW_BLOCK_SERVICE_H
+
+
+#include "SpiFlashDevice.h"
+
+//
+// Statements that include other header files
+
+#include <Library/IoLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/UefiRuntimeLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+#include <Guid/EventGroup.h>
+#include <Guid/HobList.h>
+#include <Guid/FirmwareFileSystem2.h>
+#include <Guid/SystemNvDataGuid.h>
+
+#include <Protocol/SmmBase2.h>
+#include <Protocol/LoadedImage.h>
+#include <Protocol/PlatformSmmSpiReady.h>
+
+//
+// Define two helper macro to extract the Capability field or Status field in FVB
+// bit fields
+//
+#define EFI_FVB2_CAPABILITIES (EFI_FVB2_READ_DISABLED_CAP | \
+ EFI_FVB2_READ_ENABLED_CAP | \
+ EFI_FVB2_WRITE_DISABLED_CAP | \
+ EFI_FVB2_WRITE_ENABLED_CAP | \
+ EFI_FVB2_LOCK_CAP \
+ )
+
+#define EFI_FVB2_STATUS (EFI_FVB2_READ_STATUS | EFI_FVB2_WRITE_STATUS | EFI_FVB2_LOCK_STATUS)
+
+#define EFI_INTERNAL_POINTER 0x00000004
+#define FVB_PHYSICAL 0
+#define FVB_VIRTUAL 1
+
+typedef struct {
+ EFI_LOCK FvbDevLock;
+ UINTN FvBase[2];
+ UINTN FvWriteBase[2];
+ UINTN NumOfBlocks;
+ BOOLEAN WriteEnabled;
+ EFI_FIRMWARE_VOLUME_HEADER VolumeHeader;
+} EFI_FW_VOL_INSTANCE;
+
+typedef struct {
+ UINT32 NumFv;
+ EFI_FW_VOL_INSTANCE *FvInstance[2];
+ UINT8 *FvbScratchSpace[2];
+ EFI_SPI_PROTOCOL *SpiProtocol;
+ EFI_SPI_PROTOCOL *SmmSpiProtocol;
+} ESAL_FWB_GLOBAL;
+
+//
+// SPI default opcode slots
+//
+#define SPI_OPCODE_JEDEC_ID_INDEX 0
+#define SPI_OPCODE_READ_ID_INDEX 1
+#define SPI_OPCODE_WRITE_S_INDEX 2
+#define SPI_OPCODE_WRITE_INDEX 3
+#define SPI_OPCODE_READ_INDEX 4
+#define SPI_OPCODE_ERASE_INDEX 5
+#define SPI_OPCODE_READ_S_INDEX 6
+#define SPI_OPCODE_CHIP_ERASE_INDEX 7
+
+#define SPI_ERASE_SECTOR_SIZE SIZE_4KB //This is the chipset requirement
+
+//
+// Fvb Protocol instance data
+//
+#define FVB_DEVICE_FROM_THIS(a) CR (a, EFI_FW_VOL_BLOCK_DEVICE, FwVolBlockInstance, FVB_DEVICE_SIGNATURE)
+#define FVB_EXTEND_DEVICE_FROM_THIS(a) CR (a, EFI_FW_VOL_BLOCK_DEVICE, FvbExtension, FVB_DEVICE_SIGNATURE)
+#define FVB_DEVICE_SIGNATURE SIGNATURE_32 ('F', 'V', 'B', 'C')
+//
+// Device Path
+//
+#define EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE 0xff
+#define EfiDevicePathType(a) (((a)->Type) & 0x7f)
+#define EfiIsDevicePathEndType(a) (EfiDevicePathType (a) == 0x7f)
+#define EfiIsDevicePathEndSubType(a) ((a)->SubType == EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE)
+#define EfiIsDevicePathEnd(a) (EfiIsDevicePathEndType (a) && EfiIsDevicePathEndSubType (a))
+
+typedef struct {
+ MEMMAP_DEVICE_PATH MemMapDevPath;
+ EFI_DEVICE_PATH_PROTOCOL EndDevPath;
+} FV_DEVICE_PATH;
+
+//
+// UEFI Specification define FV device path format if FV provide name GUID in extension header
+//
+typedef struct {
+ MEDIA_FW_VOL_DEVICE_PATH FvDevPath;
+ EFI_DEVICE_PATH_PROTOCOL EndDevPath;
+} UEFI_FV_DEVICE_PATH;
+
+typedef struct {
+ UINTN Signature;
+ FV_DEVICE_PATH FvDevicePath;
+ UEFI_FV_DEVICE_PATH UefiFvDevicePath;
+ UINTN Instance;
+ EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL FwVolBlockInstance;
+} EFI_FW_VOL_BLOCK_DEVICE;
+
+typedef struct {
+ EFI_PHYSICAL_ADDRESS BaseAddress;
+ EFI_FIRMWARE_VOLUME_HEADER FvbInfo;
+ //
+ // EFI_FV_BLOCK_MAP_ENTRY ExtraBlockMap[n];//n=0
+ //
+ EFI_FV_BLOCK_MAP_ENTRY End[1];
+} EFI_FVB_MEDIA_INFO;
+
+VOID
+FvbVirtualddressChangeEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+
+EFI_STATUS
+GetFvbInfo (
+ IN EFI_PHYSICAL_ADDRESS FvBaseAddress,
+ OUT EFI_FIRMWARE_VOLUME_HEADER **FvbInfo
+ );
+
+BOOLEAN
+SetPlatformFvbLock (
+ IN UINTN LbaAddress
+ );
+
+EFI_STATUS
+FvbReadBlock (
+ IN UINTN Instance,
+ IN EFI_LBA Lba,
+ IN UINTN BlockOffset,
+ IN OUT UINTN *NumBytes,
+ IN UINT8 *Buffer,
+ IN ESAL_FWB_GLOBAL *Global,
+ IN BOOLEAN Virtual
+ );
+
+EFI_STATUS
+FvbWriteBlock (
+ IN UINTN Instance,
+ IN EFI_LBA Lba,
+ IN UINTN BlockOffset,
+ IN OUT UINTN *NumBytes,
+ IN UINT8 *Buffer,
+ IN ESAL_FWB_GLOBAL *Global,
+ IN BOOLEAN Virtual
+ );
+
+EFI_STATUS
+FvbEraseBlock (
+ IN UINTN Instance,
+ IN EFI_LBA Lba,
+ IN ESAL_FWB_GLOBAL *Global,
+ IN BOOLEAN Virtual
+ );
+
+EFI_STATUS
+FvbSetVolumeAttributes (
+ IN UINTN Instance,
+ IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes,
+ IN ESAL_FWB_GLOBAL *Global,
+ IN BOOLEAN Virtual
+ );
+
+EFI_STATUS
+FvbGetVolumeAttributes (
+ IN UINTN Instance,
+ OUT EFI_FVB_ATTRIBUTES_2 *Attributes,
+ IN ESAL_FWB_GLOBAL *Global,
+ IN BOOLEAN Virtual
+ );
+
+EFI_STATUS
+FvbGetPhysicalAddress (
+ IN UINTN Instance,
+ OUT EFI_PHYSICAL_ADDRESS *Address,
+ IN ESAL_FWB_GLOBAL *Global,
+ IN BOOLEAN Virtual
+ );
+
+EFI_STATUS
+FvbInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+VOID
+FvbClassAddressChangeEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+
+EFI_STATUS
+FvbSpecificInitialize (
+ IN ESAL_FWB_GLOBAL *mFvbModuleGlobal
+ );
+
+EFI_STATUS
+FvbGetLbaAddress (
+ IN UINTN Instance,
+ IN EFI_LBA Lba,
+ OUT UINTN *LbaAddress,
+ OUT UINTN *LbaWriteAddress,
+ OUT UINTN *LbaLength,
+ OUT UINTN *NumOfBlocks,
+ IN ESAL_FWB_GLOBAL *Global,
+ IN BOOLEAN Virtual
+ );
+
+EFI_STATUS
+FvbEraseCustomBlockRange (
+ IN UINTN Instance,
+ IN EFI_LBA StartLba,
+ IN UINTN OffsetStartLba,
+ IN EFI_LBA LastLba,
+ IN UINTN OffsetLastLba,
+ IN ESAL_FWB_GLOBAL *Global,
+ IN BOOLEAN Virtual
+ );
+
+//
+// Protocol APIs
+//
+EFI_STATUS
+EFIAPI
+FvbProtocolGetAttributes (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ OUT EFI_FVB_ATTRIBUTES_2 *Attributes
+ );
+
+EFI_STATUS
+EFIAPI
+FvbProtocolSetAttributes (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes
+ );
+
+EFI_STATUS
+EFIAPI
+FvbProtocolGetPhysicalAddress (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ OUT EFI_PHYSICAL_ADDRESS *Address
+ );
+
+EFI_STATUS
+FvbProtocolGetBlockSize (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ IN EFI_LBA Lba,
+ OUT UINTN *BlockSize,
+ OUT UINTN *NumOfBlocks
+ );
+
+EFI_STATUS
+EFIAPI
+FvbProtocolRead (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ IN EFI_LBA Lba,
+ IN UINTN Offset,
+ IN OUT UINTN *NumBytes,
+ IN UINT8 *Buffer
+ );
+
+EFI_STATUS
+EFIAPI
+FvbProtocolWrite (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ IN EFI_LBA Lba,
+ IN UINTN Offset,
+ IN OUT UINTN *NumBytes,
+ IN UINT8 *Buffer
+ );
+
+EFI_STATUS
+EFIAPI
+FvbProtocolEraseBlocks (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ ...
+ );
+
+extern SPI_INIT_TABLE mSpiInitTable[];
+
+#endif
diff --git a/QuarkPlatformPkg/Platform/SpiFvbServices/PlatformSmmSpi.c b/QuarkPlatformPkg/Platform/SpiFvbServices/PlatformSmmSpi.c
new file mode 100644
index 0000000000..37c8721f3b
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/SpiFvbServices/PlatformSmmSpi.c
@@ -0,0 +1,37 @@
+/** @file
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+
+**/
+
+#include "FwBlockService.h"
+
+
+/**
+ This function allows the caller to determine if UEFI SetVirtualAddressMap() has been called.
+
+ This function returns TRUE after all the EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE functions have
+ executed as a result of the OS calling SetVirtualAddressMap(). Prior to this time FALSE
+ is returned. This function is used by runtime code to decide it is legal to access services
+ that go away after SetVirtualAddressMap().
+
+ @retval TRUE The system has finished executing the EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.
+ @retval FALSE The system has not finished executing the EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.
+
+**/
+BOOLEAN
+EfiGoneVirtual (
+ VOID
+ )
+{
+ return FALSE; //Hard coded to FALSE for SMM driver.
+}
diff --git a/QuarkPlatformPkg/Platform/SpiFvbServices/PlatformSmmSpi.inf b/QuarkPlatformPkg/Platform/SpiFvbServices/PlatformSmmSpi.inf
new file mode 100644
index 0000000000..308381f630
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/SpiFvbServices/PlatformSmmSpi.inf
@@ -0,0 +1,86 @@
+## @file
+# Component description file for SpiFvbServices Module
+#
+# Copyright (c) 2013-2015 Intel Corporation.
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = FwBlockServiceSmm
+ FILE_GUID = A469DDBD-16D0-4535-BAE3-77274BD70B4C
+ MODULE_TYPE = DXE_SMM_DRIVER
+ VERSION_STRING = 1.0
+ PI_SPECIFICATION_VERSION = 0x0001000A
+ ENTRY_POINT = FvbInitialize
+
+[Sources]
+ FwBlockService.c
+ FwBlockService.h
+ FvbInfo.c
+ SpiFlashDevice.c
+ SpiFlashDevice.h
+ PlatformSmmSpi.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ QuarkSocPkg/QuarkSocPkg.dec
+ QuarkPlatformPkg/QuarkPlatformPkg.dec
+
+[LibraryClasses]
+ IoLib
+ PcdLib
+ HobLib
+ UefiLib
+ BaseMemoryLib
+ UefiDriverEntryPoint
+ MemoryAllocationLib
+ UefiRuntimeServicesTableLib
+ UefiBootServicesTableLib
+ DxeServicesTableLib
+
+[Guids]
+ gEfiEventVirtualAddressChangeGuid
+ gEfiHobListGuid
+
+ [Protocols]
+ gEfiFirmwareVolumeBlockProtocolGuid ##Produces
+ gEfiSpiProtocolGuid
+ gEfiDevicePathProtocolGuid
+ gEfiLoadedImageProtocolGuid
+ gEfiSmmBase2ProtocolGuid
+ gEfiSmmSpiProtocolGuid
+ gEfiSmmFirmwareVolumeBlockProtocolGuid
+ gEfiSmmSpiReadyProtocolGuid
+
+[FixedPcd]
+ gQuarkPlatformTokenSpaceGuid.PcdFlashAreaSize
+
+[Pcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
+ gQuarkPlatformTokenSpaceGuid.PcdFlashAreaBaseAddress
+ gQuarkPlatformTokenSpaceGuid.PcdFlashFvMainSize
+ gQuarkPlatformTokenSpaceGuid.PcdFlashFvMainBase
+ gQuarkPlatformTokenSpaceGuid.PcdFlashFvRecoveryBase
+ gQuarkPlatformTokenSpaceGuid.PcdFlashFvRecoverySize
+ gQuarkPlatformTokenSpaceGuid.PcdFlashFvPayloadBase
+ gQuarkPlatformTokenSpaceGuid.PcdFlashFvPayloadSize
+ gQuarkPlatformTokenSpaceGuid.PcdSpiFlashDeviceSize
+
+[Depex]
+ gEfiSpiProtocolGuid
diff --git a/QuarkPlatformPkg/Platform/SpiFvbServices/PlatformSpi.inf b/QuarkPlatformPkg/Platform/SpiFvbServices/PlatformSpi.inf
new file mode 100644
index 0000000000..26648baecb
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/SpiFvbServices/PlatformSpi.inf
@@ -0,0 +1,85 @@
+## @file
+# Component description file for SpiFvbServices Module
+#
+# Copyright (c) 2013-2015 Intel Corporation.
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = FwBlockService
+ FILE_GUID = 4D35A5A7-622E-4955-A5D2-CDA812940D74
+ MODULE_TYPE = DXE_RUNTIME_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = FvbInitialize
+
+[Sources]
+ FwBlockService.c
+ FwBlockService.h
+ FvbInfo.c
+ SpiFlashDevice.c
+ SpiFlashDevice.h
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ QuarkSocPkg/QuarkSocPkg.dec
+ QuarkPlatformPkg/QuarkPlatformPkg.dec
+
+[LibraryClasses]
+ IoLib
+ PcdLib
+ HobLib
+ UefiLib
+ BaseMemoryLib
+ UefiDriverEntryPoint
+ MemoryAllocationLib
+ UefiRuntimeLib
+ UefiRuntimeServicesTableLib
+ UefiBootServicesTableLib
+ DxeServicesTableLib
+
+[Guids]
+ gEfiEventVirtualAddressChangeGuid
+ gEfiHobListGuid
+
+ [Protocols]
+ gEfiFirmwareVolumeBlockProtocolGuid ##Produces
+ gEfiSpiProtocolGuid
+ gEfiDevicePathProtocolGuid
+ gEfiLoadedImageProtocolGuid
+ gEfiSmmBase2ProtocolGuid
+ gEfiSmmSpiProtocolGuid
+ gEfiSmmFirmwareVolumeBlockProtocolGuid
+ gEfiSmmSpiReadyProtocolGuid
+
+[FixedPcd]
+ gQuarkPlatformTokenSpaceGuid.PcdFlashAreaSize
+
+[Pcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
+ gQuarkPlatformTokenSpaceGuid.PcdFlashAreaBaseAddress
+ gQuarkPlatformTokenSpaceGuid.PcdFlashFvMainSize
+ gQuarkPlatformTokenSpaceGuid.PcdFlashFvMainBase
+ gQuarkPlatformTokenSpaceGuid.PcdFlashFvRecoveryBase
+ gQuarkPlatformTokenSpaceGuid.PcdFlashFvRecoverySize
+ gQuarkPlatformTokenSpaceGuid.PcdFlashFvPayloadBase
+ gQuarkPlatformTokenSpaceGuid.PcdFlashFvPayloadSize
+ gQuarkPlatformTokenSpaceGuid.PcdSpiFlashDeviceSize
+
+[Depex]
+ gEfiSpiProtocolGuid
diff --git a/QuarkPlatformPkg/Platform/SpiFvbServices/SpiFlashDevice.c b/QuarkPlatformPkg/Platform/SpiFvbServices/SpiFlashDevice.c
new file mode 100644
index 0000000000..7f02ad3eae
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/SpiFvbServices/SpiFlashDevice.c
@@ -0,0 +1,337 @@
+/** @file
+Initializes Platform Specific Drivers.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+
+**/
+
+#include "SpiFlashDevice.h"
+
+#define FLASH_SIZE (FixedPcdGet32 (PcdFlashAreaSize))
+
+SPI_INIT_TABLE mSpiInitTable[] = {
+ //
+ // Macronix 32Mbit part
+ //
+ {
+ SPI_MX25L3205_ID1,
+ SPI_MX25L3205_ID2,
+ SPI_MX25L3205_ID3,
+ {
+ SPI_COMMAND_WRITE_ENABLE,
+ SPI_COMMAND_WRITE_S_EN
+ },
+ {
+ {EnumSpiOpcodeReadNoAddr, SPI_COMMAND_JEDEC_ID, EnumSpiCycle33MHz, EnumSpiOperationJedecId},
+ {EnumSpiOpcodeRead, SPI_COMMAND_READ_ID, EnumSpiCycle33MHz, EnumSpiOperationOther},
+ {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_WRITE_S, EnumSpiCycle33MHz, EnumSpiOperationWriteStatus},
+ {EnumSpiOpcodeWrite, SPI_COMMAND_WRITE, EnumSpiCycle33MHz, EnumSpiOperationProgramData_1_Byte},
+ {EnumSpiOpcodeRead, SPI_COMMAND_READ, EnumSpiCycle20MHz, EnumSpiOperationReadData},
+ {EnumSpiOpcodeWrite, SPI_COMMAND_BLOCK_ERASE, EnumSpiCycle33MHz, EnumSpiOperationErase_64K_Byte},
+ {EnumSpiOpcodeReadNoAddr, SPI_COMMAND_READ_S, EnumSpiCycle33MHz, EnumSpiOperationReadStatus},
+ {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_CHIP_ERASE, EnumSpiCycle33MHz, EnumSpiOperationFullChipErase}
+ },
+ 0x400000 - FLASH_SIZE, // BIOS Start Offset
+ FLASH_SIZE // BIOS image size in flash
+ },
+ //
+ // Winbond 32Mbit part
+ //
+ {
+ SPI_W25X32_ID1,
+ SF_DEVICE_ID0_W25QXX,
+ SF_DEVICE_ID1_W25Q32,
+ {
+ SPI_COMMAND_WRITE_ENABLE,
+ SPI_COMMAND_WRITE_S_EN
+ },
+ {
+ {EnumSpiOpcodeReadNoAddr, SPI_COMMAND_JEDEC_ID, EnumSpiCycle50MHz, EnumSpiOperationJedecId},
+ {EnumSpiOpcodeRead, SPI_COMMAND_READ_ID, EnumSpiCycle50MHz, EnumSpiOperationOther},
+ {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_WRITE_S, EnumSpiCycle50MHz, EnumSpiOperationWriteStatus},
+ {EnumSpiOpcodeWrite, SPI_COMMAND_WRITE, EnumSpiCycle50MHz, EnumSpiOperationProgramData_1_Byte},
+ {EnumSpiOpcodeRead, SPI_COMMAND_READ, EnumSpiCycle50MHz, EnumSpiOperationReadData},
+ {EnumSpiOpcodeWrite, SPI_COMMAND_ERASE, EnumSpiCycle50MHz, EnumSpiOperationErase_4K_Byte},
+ {EnumSpiOpcodeReadNoAddr, SPI_COMMAND_READ_S, EnumSpiCycle50MHz, EnumSpiOperationReadStatus},
+ {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_CHIP_ERASE, EnumSpiCycle50MHz, EnumSpiOperationFullChipErase}
+ },
+ 0x400000 - FLASH_SIZE, // BIOS Start Offset
+ FLASH_SIZE // BIOS image size in flash
+ },
+ //
+ // Winbond 32Mbit part
+ //
+ {
+ SPI_W25X32_ID1,
+ SPI_W25X32_ID2,
+ SPI_W25X32_ID3,
+ {
+ SPI_COMMAND_WRITE_ENABLE,
+ SPI_COMMAND_WRITE_S_EN
+ },
+ {
+ {EnumSpiOpcodeReadNoAddr, SPI_COMMAND_JEDEC_ID, EnumSpiCycle33MHz, EnumSpiOperationJedecId},
+ {EnumSpiOpcodeRead, SPI_COMMAND_READ_ID, EnumSpiCycle33MHz, EnumSpiOperationOther},
+ {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_WRITE_S, EnumSpiCycle33MHz, EnumSpiOperationWriteStatus},
+ {EnumSpiOpcodeWrite, SPI_COMMAND_WRITE, EnumSpiCycle33MHz, EnumSpiOperationProgramData_1_Byte},
+ {EnumSpiOpcodeRead, SPI_COMMAND_READ, EnumSpiCycle33MHz, EnumSpiOperationReadData},
+ {EnumSpiOpcodeWrite, SPI_COMMAND_ERASE, EnumSpiCycle33MHz, EnumSpiOperationErase_4K_Byte},
+ {EnumSpiOpcodeReadNoAddr, SPI_COMMAND_READ_S, EnumSpiCycle33MHz, EnumSpiOperationReadStatus},
+ {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_CHIP_ERASE, EnumSpiCycle33MHz, EnumSpiOperationFullChipErase}
+ },
+ 0x400000 - FLASH_SIZE, // BIOS Start Offset
+ FLASH_SIZE // BIOS image size in flash
+ },
+ //
+ // Atmel 32Mbit part
+ //
+ {
+ SPI_AT26DF321_ID1,
+ SPI_AT26DF321_ID2, // issue: byte 2 identifies family/density for Atmel
+ SPI_AT26DF321_ID3,
+ {
+ SPI_COMMAND_WRITE_ENABLE,
+ SPI_COMMAND_WRITE_S_EN
+ },
+ {
+ {EnumSpiOpcodeReadNoAddr, SPI_COMMAND_JEDEC_ID, EnumSpiCycle33MHz, EnumSpiOperationJedecId},
+ {EnumSpiOpcodeRead, SPI_COMMAND_READ_ID, EnumSpiCycle33MHz, EnumSpiOperationOther},
+ {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_WRITE_S, EnumSpiCycle33MHz, EnumSpiOperationWriteStatus},
+ {EnumSpiOpcodeWrite, SPI_COMMAND_WRITE, EnumSpiCycle33MHz, EnumSpiOperationProgramData_1_Byte},
+ {EnumSpiOpcodeRead, SPI_COMMAND_READ, EnumSpiCycle33MHz, EnumSpiOperationReadData},
+ {EnumSpiOpcodeWrite, SPI_COMMAND_BLOCK_ERASE, EnumSpiCycle33MHz, EnumSpiOperationErase_64K_Byte},
+ {EnumSpiOpcodeReadNoAddr, SPI_COMMAND_READ_S, EnumSpiCycle33MHz, EnumSpiOperationReadStatus},
+ {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_CHIP_ERASE, EnumSpiCycle33MHz, EnumSpiOperationFullChipErase}
+ },
+ 0x400000 - FLASH_SIZE, // BIOS Start Offset
+ FLASH_SIZE // BIOS image size in flash
+ },
+
+ //
+ // Intel 32Mbit part bottom boot
+ //
+ {
+ SPI_QH25F320_ID1,
+ SPI_QH25F320_ID2,
+ SPI_QH25F320_ID3,
+ {
+ SPI_COMMAND_WRITE_ENABLE,
+ SPI_COMMAND_WRITE_ENABLE
+ },
+ {
+ {EnumSpiOpcodeReadNoAddr, SPI_COMMAND_JEDEC_ID, EnumSpiCycle33MHz, EnumSpiOperationJedecId},
+ {EnumSpiOpcodeRead, SPI_COMMAND_READ_ID, EnumSpiCycle33MHz, EnumSpiOperationOther},
+ {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_WRITE_S, EnumSpiCycle33MHz, EnumSpiOperationWriteStatus},
+ {EnumSpiOpcodeWrite, SPI_COMMAND_WRITE, EnumSpiCycle33MHz, EnumSpiOperationProgramData_1_Byte},
+ {EnumSpiOpcodeRead, SPI_COMMAND_READ, EnumSpiCycle33MHz, EnumSpiOperationReadData},
+ {EnumSpiOpcodeWrite, SPI_COMMAND_BLOCK_ERASE, EnumSpiCycle33MHz, EnumSpiOperationErase_64K_Byte},
+ {EnumSpiOpcodeReadNoAddr, SPI_COMMAND_READ_S, EnumSpiCycle33MHz, EnumSpiOperationReadStatus},
+ {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_CHIP_ERASE, EnumSpiCycle33MHz, EnumSpiOperationFullChipErase}
+ },
+ 0, // BIOS Start Offset
+ FLASH_SIZE // BIOS image size in flash
+ },
+ //
+ // SST 64Mbit part
+ //
+ {
+ SPI_SST25VF080B_ID1, // VendorId
+ SF_DEVICE_ID0_25VF064C, // DeviceId 0
+ SF_DEVICE_ID1_25VF064C, // DeviceId 1
+ {
+ SPI_COMMAND_WRITE_ENABLE,
+ SPI_COMMAND_WRITE_S_EN
+ },
+ {
+ {EnumSpiOpcodeReadNoAddr, SPI_COMMAND_JEDEC_ID, EnumSpiCycle50MHz, EnumSpiOperationJedecId},
+ {EnumSpiOpcodeRead, SPI_COMMAND_READ_ID, EnumSpiCycle50MHz, EnumSpiOperationOther},
+ {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_WRITE_S, EnumSpiCycle50MHz, EnumSpiOperationWriteStatus},
+ {EnumSpiOpcodeWrite, SPI_COMMAND_WRITE, EnumSpiCycle50MHz, EnumSpiOperationProgramData_1_Byte},
+ {EnumSpiOpcodeRead, SPI_COMMAND_READ, EnumSpiCycle50MHz, EnumSpiOperationReadData},
+ {EnumSpiOpcodeWrite, SPI_COMMAND_ERASE, EnumSpiCycle50MHz, EnumSpiOperationErase_4K_Byte},
+ {EnumSpiOpcodeReadNoAddr, SPI_COMMAND_READ_S, EnumSpiCycle50MHz, EnumSpiOperationReadStatus},
+ {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_CHIP_ERASE, EnumSpiCycle50MHz, EnumSpiOperationFullChipErase}
+ },
+ 0x800000 - FLASH_SIZE, // BIOS Start Offset
+ FLASH_SIZE // BIOS image size in flash
+ },
+ //
+ // NUMONYX 64Mbit part
+ //
+ {
+ SF_VENDOR_ID_NUMONYX, // VendorId
+ SF_DEVICE_ID0_M25PX64, // DeviceId 0
+ SF_DEVICE_ID1_M25PX64, // DeviceId 1
+ {
+ SPI_COMMAND_WRITE_ENABLE,
+ SPI_COMMAND_WRITE_S_EN
+ },
+ {
+ {EnumSpiOpcodeReadNoAddr, SPI_COMMAND_JEDEC_ID, EnumSpiCycle50MHz, EnumSpiOperationJedecId},
+ {EnumSpiOpcodeRead, SPI_COMMAND_READ_ID, EnumSpiCycle50MHz, EnumSpiOperationOther},
+ {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_WRITE_S, EnumSpiCycle50MHz, EnumSpiOperationWriteStatus},
+ {EnumSpiOpcodeWrite, SPI_COMMAND_WRITE, EnumSpiCycle50MHz, EnumSpiOperationProgramData_1_Byte},
+ {EnumSpiOpcodeRead, SPI_COMMAND_READ, EnumSpiCycle50MHz, EnumSpiOperationReadData},
+ {EnumSpiOpcodeWrite, SPI_COMMAND_ERASE, EnumSpiCycle50MHz, EnumSpiOperationErase_4K_Byte},
+ {EnumSpiOpcodeReadNoAddr, SPI_COMMAND_READ_S, EnumSpiCycle50MHz, EnumSpiOperationReadStatus},
+ {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_CHIP_ERASE, EnumSpiCycle50MHz, EnumSpiOperationFullChipErase}
+ },
+ 0x800000 - FLASH_SIZE, // BIOS Start Offset
+ FLASH_SIZE // BIOS image size in flash
+ },
+ //
+ // Atmel 64Mbit part
+ //
+ {
+ SF_VENDOR_ID_ATMEL, // VendorId
+ SF_DEVICE_ID0_AT25DF641, // DeviceId 0
+ SF_DEVICE_ID1_AT25DF641, // DeviceId 1
+ {
+ SPI_COMMAND_WRITE_ENABLE,
+ SPI_COMMAND_WRITE_S_EN
+ },
+ {
+ {EnumSpiOpcodeReadNoAddr, SPI_COMMAND_JEDEC_ID, EnumSpiCycle50MHz, EnumSpiOperationJedecId},
+ {EnumSpiOpcodeRead, SPI_COMMAND_READ_ID, EnumSpiCycle50MHz, EnumSpiOperationOther},
+ {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_WRITE_S, EnumSpiCycle50MHz, EnumSpiOperationWriteStatus},
+ {EnumSpiOpcodeWrite, SPI_COMMAND_WRITE, EnumSpiCycle50MHz, EnumSpiOperationProgramData_1_Byte},
+ {EnumSpiOpcodeRead, SPI_COMMAND_READ, EnumSpiCycle50MHz, EnumSpiOperationReadData},
+ {EnumSpiOpcodeWrite, SPI_COMMAND_ERASE, EnumSpiCycle50MHz, EnumSpiOperationErase_4K_Byte},
+ {EnumSpiOpcodeReadNoAddr, SPI_COMMAND_READ_S, EnumSpiCycle50MHz, EnumSpiOperationReadStatus},
+ {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_CHIP_ERASE, EnumSpiCycle50MHz, EnumSpiOperationFullChipErase}
+ },
+ 0x800000 - FLASH_SIZE, // BIOS Start Offset
+ FLASH_SIZE // BIOS image size in flash
+ },
+
+ //
+ // Spansion 64Mbit part
+ //
+ {
+ SF_VENDOR_ID_SPANSION, // VendorId
+ SF_DEVICE_ID0_S25FL064K, // DeviceId 0
+ SF_DEVICE_ID1_S25FL064K, // DeviceId 1
+ {
+ SPI_COMMAND_WRITE_ENABLE,
+ SPI_COMMAND_WRITE_S_EN
+ },
+ {
+ {EnumSpiOpcodeReadNoAddr, SPI_COMMAND_JEDEC_ID, EnumSpiCycle50MHz, EnumSpiOperationJedecId},
+ {EnumSpiOpcodeRead, SPI_COMMAND_READ_ID, EnumSpiCycle50MHz, EnumSpiOperationOther},
+ {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_WRITE_S, EnumSpiCycle50MHz, EnumSpiOperationWriteStatus},
+ {EnumSpiOpcodeWrite, SPI_COMMAND_WRITE, EnumSpiCycle50MHz, EnumSpiOperationProgramData_1_Byte},
+ {EnumSpiOpcodeRead, SPI_COMMAND_READ, EnumSpiCycle50MHz, EnumSpiOperationReadData},
+ {EnumSpiOpcodeWrite, SPI_COMMAND_ERASE, EnumSpiCycle50MHz, EnumSpiOperationErase_4K_Byte},
+ {EnumSpiOpcodeReadNoAddr, SPI_COMMAND_READ_S, EnumSpiCycle50MHz, EnumSpiOperationReadStatus},
+ {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_CHIP_ERASE, EnumSpiCycle50MHz, EnumSpiOperationFullChipErase}
+ },
+ 0x800000 - FLASH_SIZE, // BIOS Start Offset
+ FLASH_SIZE // BIOS image size in flash
+ },
+
+ //
+ // Macronix 64Mbit part bottom boot
+ //
+ {
+ SF_VENDOR_ID_MX, // VendorId
+ SF_DEVICE_ID0_25L6405D, // DeviceId 0
+ SF_DEVICE_ID1_25L6405D, // DeviceId 1
+ {
+ SPI_COMMAND_WRITE_ENABLE,
+ SPI_COMMAND_WRITE_S_EN
+ },
+ {
+ {EnumSpiOpcodeReadNoAddr, SPI_COMMAND_JEDEC_ID, EnumSpiCycle50MHz, EnumSpiOperationJedecId},
+ {EnumSpiOpcodeRead, SPI_COMMAND_READ_ID, EnumSpiCycle50MHz, EnumSpiOperationOther},
+ {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_WRITE_S, EnumSpiCycle50MHz, EnumSpiOperationWriteStatus},
+ {EnumSpiOpcodeWrite, SPI_COMMAND_WRITE, EnumSpiCycle50MHz, EnumSpiOperationProgramData_1_Byte},
+ {EnumSpiOpcodeRead, SPI_COMMAND_READ, EnumSpiCycle50MHz, EnumSpiOperationReadData},
+ {EnumSpiOpcodeWrite, SPI_COMMAND_BLOCK_ERASE, EnumSpiCycle50MHz, EnumSpiOperationErase_64K_Byte},
+ {EnumSpiOpcodeReadNoAddr, SPI_COMMAND_READ_S, EnumSpiCycle50MHz, EnumSpiOperationReadStatus},
+ {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_CHIP_ERASE, EnumSpiCycle50MHz, EnumSpiOperationFullChipErase}
+ },
+ 0x800000 - FLASH_SIZE, // BIOS Start Offset
+ FLASH_SIZE // BIOS image size in flash
+ },
+ //
+ // Winbond 64Mbit part bottom boot
+ //
+ {
+ SPI_W25X64_ID1,
+ SF_DEVICE_ID0_W25QXX,
+ SF_DEVICE_ID1_W25Q64,
+ {
+ SPI_COMMAND_WRITE_ENABLE,
+ SPI_COMMAND_WRITE_S_EN
+ },
+ {
+ {EnumSpiOpcodeReadNoAddr, SPI_COMMAND_JEDEC_ID, EnumSpiCycle50MHz, EnumSpiOperationJedecId},
+ {EnumSpiOpcodeRead, SPI_COMMAND_READ_ID, EnumSpiCycle50MHz, EnumSpiOperationOther},
+ {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_WRITE_S, EnumSpiCycle50MHz, EnumSpiOperationWriteStatus},
+ {EnumSpiOpcodeWrite, SPI_COMMAND_WRITE, EnumSpiCycle50MHz, EnumSpiOperationProgramData_1_Byte},
+ {EnumSpiOpcodeRead, SPI_COMMAND_READ, EnumSpiCycle50MHz, EnumSpiOperationReadData},
+ {EnumSpiOpcodeWrite, SPI_COMMAND_ERASE, EnumSpiCycle50MHz, EnumSpiOperationErase_4K_Byte},
+ {EnumSpiOpcodeReadNoAddr, SPI_COMMAND_READ_S, EnumSpiCycle50MHz, EnumSpiOperationReadStatus},
+ {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_CHIP_ERASE, EnumSpiCycle50MHz, EnumSpiOperationFullChipErase}
+ },
+ 0x800000 - FLASH_SIZE, // BIOS Start Offset
+ FLASH_SIZE // BIOS image size in flash
+ },
+ //
+ // Winbond 64Mbit part bottom boot
+ //
+ {
+ SPI_W25X64_ID1,
+ SPI_W25X64_ID2,
+ SPI_W25X64_ID3,
+ {
+ SPI_COMMAND_WRITE_ENABLE,
+ SPI_COMMAND_WRITE_S_EN
+ },
+ {
+ {EnumSpiOpcodeReadNoAddr, SPI_COMMAND_JEDEC_ID, EnumSpiCycle50MHz, EnumSpiOperationJedecId},
+ {EnumSpiOpcodeRead, SPI_COMMAND_READ_ID, EnumSpiCycle50MHz, EnumSpiOperationOther},
+ {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_WRITE_S, EnumSpiCycle50MHz, EnumSpiOperationWriteStatus},
+ {EnumSpiOpcodeWrite, SPI_COMMAND_WRITE, EnumSpiCycle50MHz, EnumSpiOperationProgramData_1_Byte},
+ {EnumSpiOpcodeRead, SPI_COMMAND_READ, EnumSpiCycle50MHz, EnumSpiOperationReadData},
+ {EnumSpiOpcodeWrite, SPI_COMMAND_ERASE, EnumSpiCycle50MHz, EnumSpiOperationErase_4K_Byte},
+ {EnumSpiOpcodeReadNoAddr, SPI_COMMAND_READ_S, EnumSpiCycle50MHz, EnumSpiOperationReadStatus},
+ {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_CHIP_ERASE, EnumSpiCycle50MHz, EnumSpiOperationFullChipErase}
+ },
+ 0x800000 - FLASH_SIZE, // BIOS Start Offset
+ FLASH_SIZE // BIOS image size in flash
+ },
+ //
+ // Intel 64Mbit part bottom boot
+ //
+ {
+ SPI_QH25F640_ID1,
+ SPI_QH25F640_ID2,
+ SPI_QH25F640_ID3,
+ {
+ SPI_COMMAND_WRITE_ENABLE,
+ SPI_COMMAND_WRITE_S_EN
+ },
+ {
+ {EnumSpiOpcodeReadNoAddr, SPI_COMMAND_JEDEC_ID, EnumSpiCycle33MHz, EnumSpiOperationJedecId},
+ {EnumSpiOpcodeRead, SPI_COMMAND_READ_ID, EnumSpiCycle33MHz, EnumSpiOperationOther},
+ {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_WRITE_S, EnumSpiCycle33MHz, EnumSpiOperationWriteStatus},
+ {EnumSpiOpcodeWrite, SPI_COMMAND_WRITE, EnumSpiCycle33MHz, EnumSpiOperationProgramData_1_Byte},
+ {EnumSpiOpcodeRead, SPI_COMMAND_READ, EnumSpiCycle33MHz, EnumSpiOperationReadData},
+ {EnumSpiOpcodeWrite, SPI_COMMAND_BLOCK_ERASE, EnumSpiCycle33MHz, EnumSpiOperationErase_64K_Byte},
+ {EnumSpiOpcodeReadNoAddr, SPI_COMMAND_READ_S, EnumSpiCycle33MHz, EnumSpiOperationReadStatus},
+ {EnumSpiOpcodeWriteNoAddr, SPI_COMMAND_CHIP_ERASE, EnumSpiCycle33MHz, EnumSpiOperationFullChipErase}
+ },
+ 0x800000 - FLASH_SIZE, // BIOS Start Offset
+ FLASH_SIZE // BIOS image size in flash
+ }
+};
diff --git a/QuarkPlatformPkg/Platform/SpiFvbServices/SpiFlashDevice.h b/QuarkPlatformPkg/Platform/SpiFvbServices/SpiFlashDevice.h
new file mode 100644
index 0000000000..5fe939c8c5
--- /dev/null
+++ b/QuarkPlatformPkg/Platform/SpiFvbServices/SpiFlashDevice.h
@@ -0,0 +1,187 @@
+/** @file
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+
+**/
+
+#ifndef _SPI_FLASH_DEVICE_H_
+#define _SPI_FLASH_DEVICE_H_
+
+#include <PiDxe.h>
+#include <Protocol/Spi.h>
+#include <Protocol/FirmwareVolumeBlock.h>
+
+//
+// Supported SPI Flash Devices
+//
+typedef enum {
+ EnumSpiFlash25L3205D, // Macronix 32Mbit part
+ EnumSpiFlashW25Q32, // Winbond 32Mbit part
+ EnumSpiFlashW25X32, // Winbond 32Mbit part
+ EnumSpiFlashAT25DF321, // Atmel 32Mbit part
+ EnumSpiFlashQH25F320, // Intel 32Mbit part
+ EnumSpiFlash25VF064C, // SST 64Mbit part
+ EnumSpiFlashM25PX64, // NUMONYX 64Mbit part
+ EnumSpiFlashAT25DF641, // Atmel 64Mbit part
+ EnumSpiFlashS25FL064K, // Spansion 64Mbit part
+ EnumSpiFlash25L6405D, // Macronix 64Mbit part
+ EnumSpiFlashW25Q64, // Winbond 64Mbit part
+ EnumSpiFlashW25X64, // Winbond 64Mbit part
+ EnumSpiFlashQH25F640, // Intel 64Mbit part
+ EnumSpiFlashMax
+} SPI_FLASH_TYPES_SUPPORTED;
+
+//
+// Flash Device commands
+//
+// If a supported device uses a command different from the list below, a device specific command
+// will be defined just below it's JEDEC id section.
+//
+#define SPI_COMMAND_WRITE 0x02
+#define SPI_COMMAND_WRITE_AAI 0xAD
+#define SPI_COMMAND_READ 0x03
+#define SPI_COMMAND_ERASE 0x20
+#define SPI_COMMAND_WRITE_DISABLE 0x04
+#define SPI_COMMAND_READ_S 0x05
+#define SPI_COMMAND_WRITE_ENABLE 0x06
+#define SPI_COMMAND_READ_ID 0xAB
+#define SPI_COMMAND_JEDEC_ID 0x9F
+#define SPI_COMMAND_WRITE_S_EN 0x50
+#define SPI_COMMAND_WRITE_S 0x01
+#define SPI_COMMAND_CHIP_ERASE 0xC7
+#define SPI_COMMAND_BLOCK_ERASE 0xD8
+
+//
+// Flash JEDEC device ids
+//
+// SST 8Mbit part
+//
+#define SPI_SST25VF080B_ID1 0xBF
+#define SPI_SST25VF080B_ID2 0x25
+#define SPI_SST25VF080B_ID3 0x8E
+//
+// SST 16Mbit part
+//
+#define SPI_SST25VF016B_ID1 0xBF
+#define SPI_SST25VF016B_ID2 0x25
+#define SPI_SST25V016BF_ID3 0x41
+//
+// Macronix 32Mbit part
+//
+// MX25 part does not support WRITE_AAI comand (0xAD)
+//
+#define SPI_MX25L3205_ID1 0xC2
+#define SPI_MX25L3205_ID2 0x20
+#define SPI_MX25L3205_ID3 0x16
+//
+// Intel 32Mbit part bottom boot
+//
+#define SPI_QH25F320_ID1 0x89
+#define SPI_QH25F320_ID2 0x89
+#define SPI_QH25F320_ID3 0x12 // 32Mbit bottom boot
+//
+// Intel 64Mbit part bottom boot
+//
+#define SPI_QH25F640_ID1 0x89
+#define SPI_QH25F640_ID2 0x89
+#define SPI_QH25F640_ID3 0x13 // 64Mbit bottom boot
+//
+// QH part does not support command 0x20 for erase; only 0xD8 (sector erase)
+// QH part has 0x40 command for erase of parameter block (8 x 8K blocks at bottom of part)
+// 0x40 command ignored if address outside of parameter block range
+//
+#define SPI_QH25F320_COMMAND_PBLOCK_ERASE 0x40
+//
+// Winbond 32Mbit part
+//
+#define SPI_W25X32_ID1 0xEF
+#define SPI_W25X32_ID2 0x30 // Memory Type
+#define SPI_W25X32_ID3 0x16 // Capacity
+#define SF_DEVICE_ID1_W25Q32 0x16
+
+//
+// Winbond 64Mbit part
+//
+#define SPI_W25X64_ID1 0xEF
+#define SPI_W25X64_ID2 0x30 // Memory Type
+#define SPI_W25X64_ID3 0x17 // Capacity
+#define SF_DEVICE_ID0_W25QXX 0x40
+#define SF_DEVICE_ID1_W25Q64 0x17
+//
+// Winbond 128Mbit part
+//
+#define SF_DEVICE_ID0_W25Q128 0x40
+#define SF_DEVICE_ID1_W25Q128 0x18
+
+//
+// Atmel 32Mbit part
+//
+#define SPI_AT26DF321_ID1 0x1F
+#define SPI_AT26DF321_ID2 0x47 // [7:5]=Family, [4:0]=Density
+#define SPI_AT26DF321_ID3 0x00
+
+#define SF_VENDOR_ID_ATMEL 0x1F
+#define SF_DEVICE_ID0_AT25DF641 0x48
+#define SF_DEVICE_ID1_AT25DF641 0x00
+
+//
+// SST 8Mbit part
+//
+#define SPI_SST25VF080B_ID1 0xBF
+#define SPI_SST25VF080B_ID2 0x25
+#define SPI_SST25VF080B_ID3 0x8E
+#define SF_DEVICE_ID0_25VF064C 0x25
+#define SF_DEVICE_ID1_25VF064C 0x4B
+
+//
+// SST 16Mbit part
+//
+#define SPI_SST25VF016B_ID1 0xBF
+#define SPI_SST25VF016B_ID2 0x25
+#define SPI_SST25V016BF_ID3 0x41
+
+//
+// Winbond 32Mbit part
+//
+#define SPI_W25X32_ID1 0xEF
+#define SPI_W25X32_ID2 0x30 // Memory Type
+#define SPI_W25X32_ID3 0x16 // Capacity
+
+#define SF_VENDOR_ID_MX 0xC2
+#define SF_DEVICE_ID0_25L6405D 0x20
+#define SF_DEVICE_ID1_25L6405D 0x17
+
+#define SF_VENDOR_ID_NUMONYX 0x20
+#define SF_DEVICE_ID0_M25PX64 0x71
+#define SF_DEVICE_ID1_M25PX64 0x17
+
+//
+// Spansion 64Mbit part
+//
+#define SF_VENDOR_ID_SPANSION 0xEF
+#define SF_DEVICE_ID0_S25FL064K 0x40
+#define SF_DEVICE_ID1_S25FL064K 0x00
+
+//
+// index for prefix opcodes
+//
+#define SPI_WREN_INDEX 0 // Prefix Opcode 0: SPI_COMMAND_WRITE_ENABLE
+#define SPI_EWSR_INDEX 1 // Prefix Opcode 1: SPI_COMMAND_WRITE_S_EN
+#define BIOS_CTRL 0xDC
+
+#define PFAB_CARD_DEVICE_ID 0x5150
+#define PFAB_CARD_VENDOR_ID 0x8086
+#define PFAB_CARD_SETUP_REGISTER 0x40
+#define PFAB_CARD_SETUP_BYTE 0x0d
+
+
+#endif