* [Patch][edk2-platforms/devel-IntelAtomProcessorE3900 3/5] Library producing EEPROM raw data functionality.
2018-07-23 2:39 [Patch][edk2-platforms/devel-IntelAtomProcessorE3900 1/5] Add EepromApp zwei4
@ 2018-07-23 2:39 ` zwei4
2018-07-23 2:39 ` [Patch][edk2-platforms/devel-IntelAtomProcessorE3900 4/5] Common EEPROM library instance zwei4
2018-07-23 2:39 ` [Patch][edk2-platforms/devel-IntelAtomProcessorE3900 5/5] EEPROM header files zwei4
2 siblings, 0 replies; 4+ messages in thread
From: zwei4 @ 2018-07-23 2:39 UTC (permalink / raw)
To: edk2-devel; +Cc: David Wei, Kelly Steele, Mike Wu, Mang Guo
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: David Wei <david.wei@intel.com>
CC: Kelly Steele <kelly.steele@intel.com>
CC: Mike Wu <mike.wu@intel.com>
CC: Mang Guo <mang.guo@intel.com>
---
.../EepromDataLib/EEPROM/EepromDataEepromLib.c | 1628 ++++++++++++++++++++
.../EepromDataLib/EEPROM/EepromDataEepromLib.h | 213 +++
.../Features/Eeprom/EepromDataLib/EEPROM/HobData.c | 142 ++
.../Eeprom/EepromDataLib/EEPROM/HobDataPei.c | 123 ++
.../Features/Eeprom/EepromDataLib/EEPROM/I2cLib.c | 1164 ++++++++++++++
.../Features/Eeprom/EepromDataLib/EEPROM/I2cLib.h | 181 +++
.../Features/Eeprom/EepromDataLib/EepromDataLib.c | 216 +++
.../Features/Eeprom/EepromDataLib/EepromDataLib.h | 290 ++++
.../Eeprom/EepromDataLib/EepromDataLib.inf | 80 +
.../Eeprom/EepromDataLib/EepromDataNullLib.inf | 40 +
.../Eeprom/EepromDataLib/EepromDataPeiLib.inf | 75 +
.../Eeprom/EepromDataLib/FV/EepromDataFvLib.c | 172 +++
.../Eeprom/EepromDataLib/FV/EepromDataFvLib.h | 32 +
.../Features/Eeprom/EepromDataLib/FV/GetImage.c | 114 ++
.../Features/Eeprom/EepromDataLib/FV/GetImagePei.c | 113 ++
.../EepromDataLib/Memory/EepromDataMemoryLib.c | 242 +++
.../EepromDataLib/Memory/EepromDataMemoryLib.h | 58 +
.../Features/Eeprom/EepromDataLib/Memory/HobData.c | 142 ++
.../Eeprom/EepromDataLib/Memory/HobDataPei.c | 123 ++
.../Eeprom/EepromDataLib/MemoryAllocation.c | 67 +
.../Eeprom/EepromDataLib/MemoryAllocationPei.c | 481 ++++++
.../Eeprom/EepromDataLib/Null/EepromDataNullLib.c | 67 +
.../Eeprom/EepromDataLib/Null/EepromDataNullLib.h | 24 +
23 files changed, 5787 insertions(+)
create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/EEPROM/EepromDataEepromLib.c
create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/EEPROM/EepromDataEepromLib.h
create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/EEPROM/HobData.c
create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/EEPROM/HobDataPei.c
create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/EEPROM/I2cLib.c
create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/EEPROM/I2cLib.h
create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/EepromDataLib.c
create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/EepromDataLib.h
create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/EepromDataLib.inf
create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/EepromDataNullLib.inf
create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/EepromDataPeiLib.inf
create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/FV/EepromDataFvLib.c
create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/FV/EepromDataFvLib.h
create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/FV/GetImage.c
create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/FV/GetImagePei.c
create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/Memory/EepromDataMemoryLib.c
create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/Memory/EepromDataMemoryLib.h
create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/Memory/HobData.c
create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/Memory/HobDataPei.c
create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/MemoryAllocation.c
create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/MemoryAllocationPei.c
create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/Null/EepromDataNullLib.c
create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/Null/EepromDataNullLib.h
diff --git a/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/EEPROM/EepromDataEepromLib.c b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/EEPROM/EepromDataEepromLib.c
new file mode 100644
index 0000000000..6f8e98c38d
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/EEPROM/EepromDataEepromLib.c
@@ -0,0 +1,1628 @@
+/** @file
+ EEPROM raw data library instance.
+
+ Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
+
+ 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 "EepromDataEepromLib.h"
+
+LIST_ENTRY *gEepromPartsHeadLink = NULL;
+EEPROM_PART_INFO *gEepromParts = NULL;
+
+EFI_STATUS
+EFIAPI
+CreateBlockList (
+ IN UINT32 Offset,
+ IN UINT32 *Size,
+ IN VOID *FunctionInfo,
+ IN OUT BLOCK_LIST *BlockListHead
+ )
+{
+ UINT8 Address;
+ EEPROM_FUNCTION_INFO *EepromInfo;
+ BLOCK_LIST *BlockList;
+ UINT16 BlockOffset;
+ UINT32 ReadCount;
+ UINT32 ReadOffset;
+ EFI_STATUS Status;
+
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Starting\n", __FUNCTION__, __LINE__));
+
+ //
+ // Initialize variables
+ //
+ EepromInfo = (EEPROM_FUNCTION_INFO *) FunctionInfo;
+ Status = EFI_SUCCESS;
+
+ //
+ // Sanity checks
+ //
+ if ((Size == NULL) || (FunctionInfo == NULL) || (BlockListHead == NULL)) {
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+
+ //
+ // Debug info
+ //
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Bus = 0x%02x Address = 0x%02x\n", __FUNCTION__, __LINE__, EepromInfo->Bus, EepromInfo->Address));
+
+ //
+ // Initialize first linked entry
+ //
+ BlockList = EepromAllocatePool (sizeof (BLOCK_LIST));
+ if (BlockList == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+ BlockList->Address = EepromInfo->Address;
+ BlockList->Signature = BLOCK_LIST_SIGNATURE;
+ BlockList->Size = 0;
+ ReadCount = *Size;
+ ReadOffset = Offset;
+ while (ReadCount > 0) {
+ Address = GetMapAddress (
+ ReadOffset,
+ &BlockOffset,
+ FunctionInfo
+ );
+ if (ReadCount == *Size) {
+ //
+ // Beginning of list search.
+ //
+ BlockList->Offset = BlockOffset;
+ }
+ if (Address == BlockList->Address) {
+ //
+ // Same address range, increment size.
+ //
+ BlockList->Size++;
+ } else if (Address != INVALID_I2C_ADDRESS) {
+ //
+ // Dump this block of info
+ //
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Address = 0x%08x\n", __FUNCTION__, __LINE__, BlockList->Address));
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Offset = 0x%08x\n", __FUNCTION__, __LINE__, BlockList->Offset));
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Size = 0x%08x\n", __FUNCTION__, __LINE__, BlockList->Size));
+ //
+ // New address range, create new PageList.
+ //
+ InsertTailList (&BlockListHead->Link, &BlockList->Link);
+ BlockList = EepromAllocatePool (sizeof (BLOCK_LIST));
+ if (BlockList == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+ BlockList->Address = Address;
+ BlockList->Offset = BlockOffset;
+ BlockList->Signature = BLOCK_LIST_SIGNATURE;
+ BlockList->Size = 1;
+ } else if (BlockList->Size == 0) {
+ //
+ // GetMapAddress failed to find an address for this offset
+ //
+ Status = EFI_NO_MAPPING;
+ goto Exit;
+ }
+ //
+ // Decrement read counter
+ //
+ ReadCount--;
+ //
+ // Increment read offset
+ //
+ ReadOffset++;
+ }
+ //
+ // Dump this block of info
+ //
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Address = 0x%08x\n", __FUNCTION__, __LINE__, BlockList->Address));
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Offset = 0x%08x\n", __FUNCTION__, __LINE__, BlockList->Offset));
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Size = 0x%08x\n", __FUNCTION__, __LINE__, BlockList->Size));
+ //
+ // Insert last record
+ //
+ InsertTailList (&BlockListHead->Link, &BlockList->Link);
+
+Exit:
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - Ending with %r\n", __FUNCTION__, __LINE__, Status));
+ }
+ return Status;
+}
+
+VOID
+EFIAPI
+DestroyBlockList (
+ IN BLOCK_LIST *BlockListHead
+ )
+{
+ BLOCK_LIST *BlockList;
+ LIST_ENTRY *Node;
+
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Starting\n", __FUNCTION__, __LINE__));
+
+ //
+ // Sanity checks
+ //
+ if (BlockListHead == NULL) {
+ goto Exit;
+ }
+ if (IsListEmpty (&BlockListHead->Link)) {
+ goto Exit;
+ }
+
+ //
+ // Walk block list and free memory
+ //
+ Node = GetFirstNode (&BlockListHead->Link);
+ do {
+ BlockList = BLOCK_LIST_FROM_THIS (Node);
+ Node = GetNextNode (&BlockListHead->Link, Node);
+ RemoveEntryList (&BlockList->Link);
+ BlockList = EepromFreePool (BlockList);
+ } while (!IsNull (&BlockListHead->Link, Node));
+
+Exit:
+ //
+ // Free block list head
+ //
+ BlockListHead = EepromFreePool (BlockListHead);
+ return;
+}
+
+VOID
+EFIAPI
+DumpEepromMap (VOID)
+{
+ EEPROM_MAP_INFO *CurrentEepromMap;
+ EEPROM_PART_INFO *CurrentEepromParts;
+ LIST_ENTRY *MapNode;
+ LIST_ENTRY *PartNode;
+
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Starting\n", __FUNCTION__, __LINE__));
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - gEepromPartsHeadLink = 0x%08x\n", __FUNCTION__, __LINE__, gEepromPartsHeadLink));
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - HeadLink->ForwardLink = 0x%08x\n", __FUNCTION__, __LINE__, gEepromPartsHeadLink->ForwardLink));
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - HeadLink->BackLink = 0x%08x\n", __FUNCTION__, __LINE__, gEepromPartsHeadLink->BackLink));
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - gEepromParts = 0x%08x\n", __FUNCTION__, __LINE__, gEepromParts));
+
+ if ((gEepromParts != NULL) && (gEepromPartsHeadLink != NULL)) {
+ PartNode = GetFirstNode (gEepromPartsHeadLink);
+ do {
+ CurrentEepromParts = EEPROM_PART_INFO_FROM_THIS (PartNode);
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - PartNode = %08x HeadLink = %08x\n", __FUNCTION__, __LINE__, PartNode, gEepromPartsHeadLink));
+ DEBUG ((DEBUG_INFO, "%a (#%4d) - EEPROM bus number = 0x%08x\n", __FUNCTION__, __LINE__, CurrentEepromParts->BusNumber));
+ DEBUG ((DEBUG_INFO, "%a (#%4d) - EEPROM address = 0x%08x\n", __FUNCTION__, __LINE__, CurrentEepromParts->Address));
+ DEBUG ((DEBUG_INFO, "%a (#%4d) - EEPROM speed = 0x%08x\n", __FUNCTION__, __LINE__, CurrentEepromParts->PartSpeed));
+ DEBUG ((DEBUG_INFO, "%a (#%4d) - EEPROM part size = 0x%08x\n", __FUNCTION__, __LINE__, CurrentEepromParts->PartSize));
+ DEBUG ((DEBUG_INFO, "%a (#%4d) - EEPROM block length = 0x%08x\n", __FUNCTION__, __LINE__, CurrentEepromParts->BlockLength));
+ DEBUG ((DEBUG_INFO, "%a (#%4d) - EEPROM page size = 0x%08x\n", __FUNCTION__, __LINE__, CurrentEepromParts->PageSize));
+ DEBUG ((DEBUG_INFO, "%a (#%4d) - EEPROM master map = 0x%08x\n", __FUNCTION__, __LINE__, CurrentEepromParts->Master));
+ //
+ // Dump map records
+ //
+ MapNode = GetFirstNode (&CurrentEepromParts->MapHeadLink);
+ do {
+ CurrentEepromMap = EEPROM_MAP_INFO_FROM_THIS (MapNode);
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - MapNode = %08x HeadLink = %08x\n", __FUNCTION__, __LINE__, MapNode, &CurrentEepromParts->MapHeadLink));
+ DEBUG ((DEBUG_INFO, "%a (#%4d) - Address = 0x%08x\n", __FUNCTION__, __LINE__, CurrentEepromMap->Address));
+ DEBUG ((DEBUG_INFO, "%a (#%4d) - Offset = 0x%08x\n", __FUNCTION__, __LINE__, CurrentEepromMap->Offset));
+ //
+ // Get next record
+ //
+ MapNode = GetNextNode (&CurrentEepromParts->MapHeadLink, MapNode);
+ } while (!IsNull (&CurrentEepromParts->MapHeadLink, MapNode));
+ //
+ // Get next record
+ //
+ PartNode = GetNextNode (gEepromPartsHeadLink, PartNode);
+ } while (!IsNull (gEepromPartsHeadLink, PartNode));
+ } else {
+ DEBUG ((DEBUG_INFO, "%a (#%4d) - WARNING: gEepromParts or gEepromPartsHeadLink is bad!\n", __FUNCTION__, __LINE__));
+ }
+}
+
+EFI_STATUS
+EFIAPI
+FillEepromMap (
+ IN OUT VOID *FunctionInfo
+ )
+{
+ CHAR8 AsciiBuffer[32];
+ UINT8 *Buffer;
+ BOOLEAN CheckBuffer;
+ EEPROM_MAP_INFO *CurrentEepromMap;
+ EEPROM_PART_INFO *CurrentEepromParts;
+ EEPROM_MAP *EepromHeader;
+ EEPROM_FUNCTION_INFO *EepromInfo;
+ UINT32 index;
+ EEPROM_MAP_RECORD *MapRecord;
+ UINT32 MaxRecord;
+ UINT8 *Ptr;
+ UINT32 Size;
+ EFI_STATUS Status;
+
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Starting\n", __FUNCTION__, __LINE__));
+
+ //
+ // Initialize variables
+ //
+ Buffer = NULL;
+ CurrentEepromParts = NULL;
+ EepromInfo = NULL;
+
+ //
+ // Sanity checks
+ //
+ if (FunctionInfo == NULL) {
+ //
+ // EEPROM function info is outside of range. Bail.
+ //
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: FunctionInfo == NULL!\n", __FUNCTION__, __LINE__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ } else {
+ EepromInfo = (EEPROM_FUNCTION_INFO *) FunctionInfo;
+ if (EepromInfo->Buffer != NULL) {
+ CheckBuffer = TRUE;
+ } else {
+ CheckBuffer = FALSE;
+ }
+ }
+ if (CheckBuffer) {
+ //
+ // We'll be checking the passed in buffer for the map.
+ //
+ if ((EepromInfo->Buffer == NULL) || (EepromInfo->Size == 0)) {
+ //
+ // EEPROM function info is outside of range. Bail.
+ //
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: FunctionInfo->Buffer == NULL or FunctionInfo->Size == 0!\n", __FUNCTION__, __LINE__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ }
+ if ((EepromInfo->Bus > MAX_I2C_BUS) || (EepromInfo->Address > MAX_I2C_ADDRESS)) {
+ //
+ // EEPROM function info is outside of range. Bail.
+ //
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: FunctionInfo->Bus > 7 or FunctionInfo->Address >= 0x80!\n", __FUNCTION__, __LINE__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+
+ //
+ // Debug info
+ //
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - gEepromPartsHeadLink = 0x%08x gEepromParts = 0x%08x\n", __FUNCTION__, __LINE__, gEepromPartsHeadLink, gEepromParts));
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Bus = 0x%02x Address = 0x%02x\n", __FUNCTION__, __LINE__, EepromInfo->Bus, EepromInfo->Address));
+
+ //
+ // Is our map valid?
+ //
+ if ((gEepromParts != NULL) && (gEepromPartsHeadLink != NULL)) {
+ //
+ // Parse list of part records to see if we already have this map.
+ //
+ if (SearchEepromPartList (EepromInfo->Bus, EepromInfo->Address) != NULL) {
+ //
+ // Yep. Bail.
+ //
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Already have valid EEPROM map.\n", __FUNCTION__, __LINE__));
+ Status = EFI_SUCCESS;
+ goto Exit;
+ } else {
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Failed to find EEPROM map. Trying to add it.\n", __FUNCTION__, __LINE__));
+ }
+ } else {
+ //
+ // Make sure our parts buffer is pointing to NULL.
+ //
+ gEepromPartsHeadLink = EepromFreePool (gEepromPartsHeadLink);
+ gEepromParts = EepromFreePool (gEepromParts);
+ }
+
+ //
+ // Create read buffer
+ //
+ if (CheckBuffer) {
+ //
+ // Use the passed in buffer.
+ //
+ Buffer = EepromInfo->Buffer;
+ } else {
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Allocating buffer to hold first 4KB.\n", __FUNCTION__, __LINE__));
+ Size = 4 * 1024;
+ Buffer = EepromAllocatePool (Size);
+ if (Buffer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+ }
+
+ //
+ // Fill in map
+ // 1. Read in 4KB from PcdEepromBus|PcdEepromAddress.
+ // 2. Jump the structures looking for $EeprMap structure.
+ // 3. Load EEPROM map records from this structure.
+ //
+ if (CheckBuffer) {
+ Size = EepromInfo->Size;
+ } else {
+ //
+ // Step #1: Load buffer with first 4KB of data from the EEPROM
+ //
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Reading first 4KB of EEPROM data.\n", __FUNCTION__, __LINE__));
+ //
+ // Read EEPROM
+ //
+ Ptr = Buffer;
+ Size = 4 * 1024;
+ //
+ // Get first 8 bytes
+ //
+ Status = I2cReadPages (EepromInfo->Bus, EepromInfo->Address, 0, 8, Ptr);
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
+ //
+ // Sanity check EEPROM contents
+ //
+ AsciiSPrint (AsciiBuffer, 32, "%8a", (CHAR8 *) Ptr);
+ if (AsciiStrnCmp (AsciiBuffer, "$Eeprom$", 0x08) != 0) {
+ //
+ // Not a vallid EEPROM image. Bail.
+ //
+ Status = EFI_NO_MAPPING;
+ goto Exit;
+ }
+ //
+ // Read in 4KB
+ //
+ Ptr = Buffer;
+ Status = I2cReadPages (EepromInfo->Bus, EepromInfo->Address, 0, Size, Ptr);
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
+ }
+
+ //
+ // Step #2: Search for $EeprMap
+ //
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Looking for $EeprMap structure.\n", __FUNCTION__, __LINE__));
+ Status = EFI_NO_MAPPING;
+ EepromHeader = (EEPROM_MAP *) Buffer;
+ Ptr = Buffer;
+ while (Ptr[0] == '$') {
+ AsciiSPrint (AsciiBuffer, 32, "%8a", EepromHeader->signature);
+ AsciiBuffer[8] = 0;
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Structure = %a @ 0x%08x\n", __FUNCTION__, __LINE__, AsciiBuffer, EepromHeader));
+ if (AsciiStrnCmp (EepromHeader->signature, "$EeprMap", 0x08) != 0) {
+ //
+ // This is not our structure. Skip to next structure.
+ //
+ EepromHeader = (EEPROM_MAP *) ((UINT8 *) EepromHeader + EepromHeader->length + (EepromHeader->length % 0x10));
+ if ((UINT8 *) EepromHeader > (Buffer + Size)) {
+ //
+ // Didn't find $EeprMap structure
+ //
+ Status = EFI_NO_MAPPING;
+ break;
+ } else {
+ continue;
+ }
+ } else {
+ //
+ // Found $EeprMap. Create memory buffer.
+ //
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Allocating buffer to hold new EEPROM map.\n", __FUNCTION__, __LINE__));
+ CurrentEepromParts = EepromAllocatePool (sizeof (EEPROM_PART_INFO));
+ if (CurrentEepromParts == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+ //
+ // Copy data into new EEPROM map
+ //
+ CurrentEepromParts->Signature = EEPROM_PART_INFO_SIGNATURE;
+ CurrentEepromParts->Address = EepromInfo->Address;
+ CurrentEepromParts->BusNumber = EepromInfo->Bus;
+ CurrentEepromParts->PartSpeed = EepromHeader->speed;
+ CurrentEepromParts->PartSize = EepromHeader->partsize;
+ CurrentEepromParts->BlockLength = EepromHeader->blklength;
+ CurrentEepromParts->PageSize = EepromHeader->pagesize;
+ CurrentEepromParts->Master = EepromHeader->master;
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - EEPROM bus number = 0x%08x\n", __FUNCTION__, __LINE__, CurrentEepromParts->BusNumber));
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - EEPROM address = 0x%08x\n", __FUNCTION__, __LINE__, CurrentEepromParts->Address));
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - EEPROM speed = 0x%08x\n", __FUNCTION__, __LINE__, CurrentEepromParts->PartSpeed));
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - EEPROM part size = 0x%08x\n", __FUNCTION__, __LINE__, CurrentEepromParts->PartSize));
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - EEPROM block length = 0x%08x\n", __FUNCTION__, __LINE__, CurrentEepromParts->BlockLength));
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - EEPROM master map = 0x%08x\n", __FUNCTION__, __LINE__, CurrentEepromParts->Master));
+ Status = EFI_SUCCESS;
+ break;
+ }
+ };
+ //
+ // Check for error condition
+ //
+ if (EFI_ERROR (Status)) {
+ //
+ // Failed to find $EeprMap
+ //
+ Status = EFI_NO_MAPPING;
+ goto Exit;
+ }
+ //
+ // Insert record
+ //
+ if (gEepromParts == NULL) {
+ // First record, setup head link
+ gEepromParts = CurrentEepromParts;
+ gEepromPartsHeadLink = EepromAllocatePool (sizeof (LIST_ENTRY));
+ if (gEepromPartsHeadLink == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+ InitializeListHead (gEepromPartsHeadLink);
+ }
+ InsertTailList (gEepromPartsHeadLink, &CurrentEepromParts->Link);
+
+ //
+ // Step #3: Load in EEPROM map records
+ //
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Loading EEPROM map.\n", __FUNCTION__, __LINE__));
+ MapRecord = (EEPROM_MAP_RECORD *) ((UINT8 *) EepromHeader + sizeof (EEPROM_MAP));
+ MaxRecord = (UINT32) (((UINT8 *) EepromHeader + EepromHeader->length) - (UINT8 *) MapRecord) / sizeof (EEPROM_MAP_RECORD);
+ index = 0;
+ while (index < MaxRecord) {
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - 0x%08x of 0x%08x @ 0x%08x\n", __FUNCTION__, __LINE__, index, MaxRecord, MapRecord));
+ //
+ // Need a new link record
+ //
+ CurrentEepromMap = EepromAllocatePool (sizeof (EEPROM_MAP_INFO));
+ if (CurrentEepromMap == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+ //
+ // Update memory EEPROM map
+ //
+ CurrentEepromMap->Signature = EEPROM_MAP_INFO_SIGNATURE;
+ CurrentEepromMap->Address = MapRecord->address;
+ CurrentEepromMap->Offset = MapRecord->offset;
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Map[%04x] = %08x\n", __FUNCTION__, __LINE__, index, CurrentEepromMap));
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Address[%04x] = %08x\n", __FUNCTION__, __LINE__, index, CurrentEepromMap->Address));
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Offset[%04x] = %08x\n", __FUNCTION__, __LINE__, index, CurrentEepromMap->Offset));
+ //
+ // Insert record
+ //
+ if (index == 0) {
+ // First record, setup head link
+ InitializeListHead (&CurrentEepromParts->MapHeadLink);
+ }
+ InsertTailList (&CurrentEepromParts->MapHeadLink, &CurrentEepromMap->Link);
+ //
+ // Point to next record
+ //
+ MapRecord++;
+ index++;
+ }
+
+ //
+ // Set flag
+ //
+ Status = EFI_SUCCESS;
+
+Exit:
+ //
+ // Free resources
+ //
+ Buffer = EepromFreePool (Buffer);
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - Ending with %r\n", __FUNCTION__, __LINE__, Status));
+ }
+ return Status;
+}
+
+UINT8
+EFIAPI
+GetMapAddress (
+ IN UINT32 ReadOffset,
+ OUT UINT16 *BlockOffset,
+ IN VOID *FunctionInfo
+ )
+{
+ EEPROM_FUNCTION_INFO *EepromInfo;
+ EEPROM_MAP_INFO *EepromMapInfo;
+ EEPROM_PART_INFO *EepromPartInfo;
+
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Starting\n", __FUNCTION__, __LINE__));
+
+ //
+ // Initialize variables
+ //
+ EepromInfo = (EEPROM_FUNCTION_INFO *) FunctionInfo;
+
+ //
+ // Sanity Checks
+ //
+ if ((BlockOffset == NULL) || (FunctionInfo == NULL)){
+ goto Exit;
+ }
+
+ //
+ // Get part info
+ //
+ EepromPartInfo = SearchEepromPartList (EepromInfo->Bus, EepromInfo->Address);
+ if (EepromPartInfo != NULL) {
+ //
+ // Found the right EEPROM part record.
+ //
+ EepromMapInfo = SearchEepromMapList (EepromPartInfo, INVALID_I2C_ADDRESS, ReadOffset);
+ if (EepromMapInfo != NULL) {
+ //
+ // Found the right EEPROM part/map record. Return block offset and I2C address.
+ //
+ *BlockOffset = (UINT16) ((ReadOffset % EepromPartInfo->BlockLength) & 0xFFFF);
+ return EepromMapInfo->Address;
+ }
+ }
+
+Exit:
+ return INVALID_I2C_ADDRESS;
+}
+
+EFI_STATUS
+EFIAPI
+I2cReadPages (
+ IN UINT8 Bus,
+ IN UINT8 Address,
+ IN UINT16 Offset,
+ IN UINT32 Size,
+ IN OUT UINT8 *Buffer
+ )
+{
+ UINT32 CurrentCount;
+ UINT16 CurrentOffset;
+ EEPROM_PART_INFO *EepromPartInfo;
+ UINT32 I2cBaseAddress;
+ UINT16 index;
+ UINT8 PageOffset[2];
+ UINT16 PageSize;
+ UINT8 PartSpeed;
+ UINT8 *Ptr;
+ UINT32 ReadCount;
+ UINT16 RetryCount;
+ EFI_STATUS Status;
+
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Starting\n", __FUNCTION__, __LINE__));
+
+ //
+ // Initialize variables
+ //
+ CurrentCount = 0;
+ EepromPartInfo = SearchEepromPartList (Bus, Address);
+ I2cBaseAddress = 0;
+ Ptr = Buffer;
+ RetryCount = 3;
+
+ //
+ // Sanity checks
+ //
+ if (Ptr == NULL) {
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ if ((Bus > MAX_I2C_BUS) || (Address > MAX_I2C_ADDRESS)) {
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ //
+ // Set page size & part speed
+ //
+ if (EepromPartInfo == NULL) {
+ //
+ // No page size available. Use default size.
+ //
+ PageSize = DEFAULT_PAGE_SIZE;
+ PartSpeed = Standard_Speed; // default to 100KHz (Standard speed)
+ } else {
+ PageSize = EepromPartInfo->PageSize;
+ PartSpeed = EepromPartInfo->PartSpeed;
+ }
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Bus = %02x Address = %02x\n", __FUNCTION__, __LINE__, Bus, Address));
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Offset = %08x Size = %08x\n", __FUNCTION__, __LINE__, Offset, Size));
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - PageSize = %02x PartSpeed = %02x\n", __FUNCTION__, __LINE__, PageSize, PartSpeed));
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Buffer = %08x\n", __FUNCTION__, __LINE__, Buffer));
+ //
+ // Init I2C controller
+ //
+ Status = I2cInit (Bus, Address, PartSpeed, &I2cBaseAddress);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - I2cInit() = %r\n", __FUNCTION__, __LINE__, Status));
+ goto Exit;
+ }
+ //
+ // Read data from part
+ //
+ while (CurrentCount < Size) {
+ //
+ // Set offset
+ //
+ CurrentOffset = (UINT16) (Offset + CurrentCount);
+ //
+ // Calculate ReadCount
+ //
+ ReadCount = PageSize;
+ if ((Size - CurrentCount) < PageSize) {
+ ReadCount = Size - CurrentCount;
+ }
+ //
+ // Adjust for page boundaries
+ //
+ if (((CurrentOffset % PageSize) + ReadCount) > PageSize) {
+ //
+ // Read to page boundary
+ //
+ ReadCount = PageSize - (CurrentOffset % PageSize);
+ }
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Size = %08x\n", __FUNCTION__, __LINE__, Size));
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - CurrentCount = %08x\n", __FUNCTION__, __LINE__, CurrentCount));
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - PageSize = %08x\n", __FUNCTION__, __LINE__, PageSize));
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - ReadCount = %08x\n", __FUNCTION__, __LINE__, ReadCount));
+ //
+ // Set offset
+ //
+ PageOffset[0] = (CurrentOffset >> 8) & 0xFF; // MSB offset
+ PageOffset[1] = (CurrentOffset >> 0) & 0xFF; // LSB offset
+ Status = I2cSetOffset (I2cBaseAddress, PageOffset, 2);
+ if (EFI_ERROR (Status)) {
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_ERROR, "%a (#%4d) - I2cSetOffset() = %r [%02x:%02x:%04x]\n", __FUNCTION__, __LINE__, Status, Bus, Address, (Offset + CurrentCount)));
+ goto Exit;
+ }
+ //
+ // Read a page
+ //
+ for (index = 0; index < ReadCount; index++) {
+ if ((index == 0) && (ReadCount - 1 != index)) {
+ // First byte, but not only byte
+ Status = I2cRead (I2cBaseAddress, Ptr, TRUE, FALSE);
+ } else if ((index == 0) && (ReadCount - 1 == index)) {
+ // First and only byte
+ Status = I2cRead (I2cBaseAddress, Ptr, TRUE, TRUE);
+ } else if (ReadCount - 1 == index) {
+ // Last byte of page
+ Status = I2cRead (I2cBaseAddress, Ptr, FALSE, TRUE);
+ } else {
+ // Everything else
+ Status = I2cRead (I2cBaseAddress, Ptr, FALSE, FALSE);
+ }
+ if (EFI_ERROR (Status)) {
+ //
+ // Something went wrong. Bail from this for loop.
+ //
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - I2cRead() = %r\n", __FUNCTION__, __LINE__, Status));
+ break;
+ }
+ Ptr++;
+ }
+ //
+ // Check for error condition and try it again
+ //
+ if (Status == EFI_NO_RESPONSE) {
+ //
+ // Nobody home at this slave address
+ //
+ goto Exit;
+ }
+ if (EFI_ERROR (Status)) {
+ if (RetryCount-- > 0) {
+ //
+ // Try it again.
+ //
+ Ptr = &Buffer[CurrentCount];
+ } else {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - Offset = %08x\n", __FUNCTION__, __LINE__, (Offset + CurrentCount + index)));
+ goto Exit;
+ }
+ } else {
+ //
+ // Update variables
+ //
+ CurrentCount += ReadCount;
+ }
+ }
+
+Exit:
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - Ending with %r\n", __FUNCTION__, __LINE__, Status));
+ }
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+I2cWritePages (
+ IN UINT8 Bus,
+ IN UINT8 Address,
+ IN UINT16 Offset,
+ IN UINT32 Size,
+ IN OUT UINT8 *Buffer
+ )
+{
+ UINT32 CurrentCount;
+ UINT16 CurrentOffset;
+ EEPROM_PART_INFO *EepromPartInfo;
+ UINT32 I2cBaseAddress;
+ UINT16 index;
+ UINT8 PageOffset[2];
+ UINT16 PageSize;
+ UINT8 PartSpeed;
+ UINT8 *Ptr;
+ UINT16 RetryCount;
+ EFI_STATUS Status;
+ UINT32 WriteCount;
+
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Starting\n", __FUNCTION__, __LINE__));
+
+ //
+ // Initialize variables
+ //
+ CurrentCount = 0;
+ EepromPartInfo = SearchEepromPartList (Bus, Address);
+ I2cBaseAddress = 0;
+ Ptr = Buffer;
+ RetryCount = 3;
+
+ //
+ // Sanity checks
+ //
+ if (Ptr == NULL) {
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ if ((Bus > MAX_I2C_BUS) || (Address > MAX_I2C_ADDRESS)) {
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ //
+ // Set page size & part speed
+ //
+ if (EepromPartInfo == NULL) {
+ //
+ // No page size available. Assume 32 bytes per page.
+ //
+ PageSize = 32;
+ PartSpeed = 1; // default to 100KHz (Standard speed)
+ } else {
+ PageSize = EepromPartInfo->PageSize;
+ PartSpeed = EepromPartInfo->PartSpeed;
+ }
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Bus = %02x Address = %02x\n", __FUNCTION__, __LINE__, Bus, Address));
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Offset = %08x Size = %08x\n", __FUNCTION__, __LINE__, Offset, Size));
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - PageSize = %02x PartSpeed = %02x\n", __FUNCTION__, __LINE__, PageSize, PartSpeed));
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Buffer = %08x\n", __FUNCTION__, __LINE__, Buffer));
+ //
+ // Init I2C controller
+ //
+ Status = I2cInit (Bus, Address, PartSpeed, &I2cBaseAddress);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - I2cInit() = %r\n", __FUNCTION__, __LINE__, Status));
+ goto Exit;
+ }
+ //
+ // Write data to part
+ //
+ while (CurrentCount < Size) {
+ //
+ // Set pointer
+ //
+ Ptr = &Buffer[CurrentCount];
+ //
+ // Set offset
+ //
+ CurrentOffset = (UINT16) (Offset + CurrentCount);
+ //
+ // Calculate WriteCount
+ //
+ WriteCount = PageSize;
+ if ((Size - CurrentCount) < PageSize) {
+ WriteCount = Size - CurrentCount;
+ }
+ //
+ // Adjust for page boundaries
+ //
+ if (((CurrentOffset % PageSize) + WriteCount) > PageSize) {
+ //
+ // Write to page boundary
+ //
+ WriteCount = PageSize - (CurrentOffset % PageSize);
+ }
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Size = %08x\n", __FUNCTION__, __LINE__, Size));
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - CurrentCount = %08x\n", __FUNCTION__, __LINE__, CurrentCount));
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - PageSize = %08x\n", __FUNCTION__, __LINE__, PageSize));
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - WriteCount = %08x\n", __FUNCTION__, __LINE__, WriteCount));
+ //
+ // Set offset
+ //
+ PageOffset[0] = (CurrentOffset >> 8) & 0xFF; // MSB offset
+ PageOffset[1] = (CurrentOffset >> 0) & 0xFF; // LSB offset
+ Status = I2cSetOffset (I2cBaseAddress, PageOffset, 2);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - I2cSetOffset() = %r\n", __FUNCTION__, __LINE__, Status));
+ goto Exit;
+ }
+ //
+ // Write a page
+ //
+ for (index = 0; index < WriteCount; index++) {
+ if (WriteCount - 1 == index) {
+ // Last byte of the page
+ Status = I2cWrite (I2cBaseAddress, *Ptr, FALSE, TRUE);
+ } else {
+ // Everything else
+ Status = I2cWrite (I2cBaseAddress, *Ptr, FALSE, FALSE);
+ }
+ if (EFI_ERROR (Status)) {
+ //
+ // Something went wrong. Bail from this for loop.
+ //
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - I2cWrite() = %r\n", __FUNCTION__, __LINE__, Status));
+ break;
+ }
+ Ptr++;
+ }
+ if (Status == EFI_NO_RESPONSE) {
+ //
+ // Nobody home at this slave address
+ //
+ goto Exit;
+ }
+ //
+ // Check for error condition and try it again
+ //
+ if (EFI_ERROR (Status)) {
+ if (RetryCount-- == 0) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - Offset = %08x\n", __FUNCTION__, __LINE__, (Offset + CurrentCount + index)));
+ goto Exit;
+ }
+ } else {
+ //
+ // Update variables
+ //
+ CurrentCount += WriteCount;
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - CurrentCount = %08x WriteCount = %08x\n", __FUNCTION__, __LINE__, CurrentCount, WriteCount));
+ }
+ //
+ // Make sure write is done
+ //
+ Status = I2cPoll (I2cBaseAddress);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - I2cPoll() = %r\n", __FUNCTION__, __LINE__, Status));
+ goto Exit;
+ }
+ }
+
+Exit:
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - Ending with %r\n", __FUNCTION__, __LINE__, Status));
+ }
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+LoadEepromMap (VOID)
+{
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+ReadEepromBlockList (
+ IN OUT UINT8 *Buffer,
+ IN VOID *FunctionInfo,
+ IN BLOCK_LIST *BlockListHead
+ )
+{
+ BLOCK_LIST *CurrentBlockList;
+ EEPROM_FUNCTION_INFO *EepromInfo;
+ LIST_ENTRY *Node;
+ UINT8 *Ptr;
+ UINT32 ReadCount;
+ EFI_STATUS Status;
+
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Starting\n", __FUNCTION__, __LINE__));
+
+ //
+ // Initialize variables
+ //
+ EepromInfo = (EEPROM_FUNCTION_INFO *) FunctionInfo;
+ Ptr = Buffer;
+ ReadCount = 0;
+ Status = EFI_SUCCESS;
+
+ //
+ // Sanity checks
+ //
+ if ((Buffer == NULL) || (FunctionInfo == NULL) || (BlockListHead == NULL)) {
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+
+ //
+ // Read data into buffer
+ //
+ DEBUG ((DEBUG_INFO, "%a (#%4d) - Reading from EEPROM...\n", __FUNCTION__, __LINE__));
+ Node = GetFirstNode (&BlockListHead->Link);
+ do {
+ //
+ // Read in a block
+ //
+ CurrentBlockList = BLOCK_LIST_FROM_THIS (Node);
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - buffer @ %08x\n", __FUNCTION__, __LINE__, Buffer));
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - bus = %08x\n", __FUNCTION__, __LINE__, EepromInfo->Bus));
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - address = %08x\n", __FUNCTION__, __LINE__, CurrentBlockList->Address));
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - offset = %08x\n", __FUNCTION__, __LINE__, CurrentBlockList->Offset));
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - ptr @ %08x\n", __FUNCTION__, __LINE__, Ptr));
+ Status = I2cReadPages (EepromInfo->Bus, CurrentBlockList->Address, CurrentBlockList->Offset, CurrentBlockList->Size, Ptr);
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
+ //
+ // Get next record
+ //
+ Ptr += CurrentBlockList->Size;
+ Node = GetNextNode (&BlockListHead->Link, Node);
+ } while (!IsNull (&BlockListHead->Link, Node));
+
+Exit:
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - Ending with %r\n", __FUNCTION__, __LINE__, Status));
+ }
+ return Status;
+}
+
+//
+// Desc: Reads from the EEPROM and copies to the passed in buffer.
+// Variables: Offset Start copying from the offset
+// Size Size of the buffer and the number of bytes to copy
+// - If size = 0, then return image size
+// Buffer Storage buffer for the copied data from the EEPROM
+// FunctionInfo Pointer to function specific data
+// Return: EFI_SUCCESS Data copied successfully
+// EFI_UNSUPPORTED This function is not supported
+// EFI_INVALID_PARAMETER One of the parameters is invalid
+// EFI_NOT_READY Called before all necessary protocols available
+// EFI_DEVICE_ERROR Communication error with device
+//
+EFI_STATUS
+EFIAPI
+ReadEepromEeprom (
+ IN UINT32 Offset,
+ IN OUT UINT32 *Size,
+ IN OUT UINT8 *Buffer,
+ IN OUT VOID *FunctionInfo
+ )
+{
+ BLOCK_LIST *BlockList;
+ EEPROM_FUNCTION_INFO *EepromInfo;
+ EEPROM_PART_INFO *EepromPartInfo;
+ EFI_STATUS Status;
+
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Starting\n", __FUNCTION__, __LINE__));
+
+ //
+ // Initialize variables
+ //
+ BlockList = NULL;
+ EepromInfo = (EEPROM_FUNCTION_INFO *) FunctionInfo;
+ EepromPartInfo = NULL;
+ Status = EFI_SUCCESS;
+ LoadEepromMap ();
+
+ //
+ // Sanity checks
+ //
+ // NOTE: Input parameters already checked in wrapper function.
+ //
+ if (FunctionInfo == NULL) {
+ //
+ // This needs to be pointing to something. Bail.
+ //
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_ERROR, "%a (#%4d) - FunctionInfo == NULL!\n", __FUNCTION__, __LINE__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ if (EepromInfo->LibraryIndex != EEPROM_EEPROM) {
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_ERROR, "%a (#%4d) - LibraryIndex != EEPROM_EEPROM!\n", __FUNCTION__, __LINE__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+
+ //
+ // Scan I2C bus for images?
+ //
+ if (EepromInfo->ScanSize != NULL) {
+ Status = ScanI2cBusForImages (EepromInfo->Bus, &(EepromInfo->ScanBuffer), EepromInfo->ScanSize);
+ goto Exit;
+ }
+
+ //
+ // Make sure we have the EEPROM map for this part
+ //
+ Status = FillEepromMap (FunctionInfo);
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
+
+ //
+ // Dump current mappings
+ //
+ DumpEepromMap ();
+
+ //
+ // Do they just want the size of the EEPROM part?
+ //
+ if (*Size == 0) {
+ //
+ // Return EEPROM part size
+ //
+ EepromPartInfo = SearchEepromPartList (EepromInfo->Bus, EepromInfo->Address);
+ if (EepromPartInfo == NULL) {
+ //
+ // Failed to find part info. Bail.
+ //
+ Status = EFI_NO_MAPPING;
+ } else {
+ //
+ // Return EEPROM part size.
+ //
+ *Size = EepromPartInfo->PartSize;
+ Status = EFI_BUFFER_TOO_SMALL;
+ }
+ goto Exit;
+ }
+
+ //
+ // Initialize block list head
+ //
+ BlockList = EepromAllocatePool (sizeof (BLOCK_LIST));
+ InitializeListHead (&BlockList->Link);
+
+ //
+ // Create list of blocks to read
+ //
+ Status = CreateBlockList (
+ Offset, // Offset in EEPROM to start reading data from
+ Size, // Number of bytes to read
+ FunctionInfo, // Pointer to function specific data
+ BlockList // Head block list
+ );
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - CreateBlockList() = %r\n", __FUNCTION__, __LINE__, Status));
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
+
+ //
+ // Read the list into the buffer
+ //
+ Status = ReadEepromBlockList (
+ Buffer,
+ FunctionInfo,
+ BlockList
+ );
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - ReadEepromBlockList() = %r\n", __FUNCTION__, __LINE__, Status));
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
+
+Exit:
+ //
+ // Free resources
+ //
+ DestroyBlockList (BlockList);
+
+ if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - Ending with %r\n", __FUNCTION__, __LINE__, Status));
+ }
+ //
+ // Save off pointers for use across LIB instances
+ //
+ SaveEepromMap ();
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+SaveEepromMap (VOID)
+{
+ //
+ // Initialize variables
+ //
+ PcdSet64S (PcdEepromParts, (UINTN) gEepromParts);
+ PcdSet64S (PcdEepromPartsHeadLink, (UINTN) gEepromPartsHeadLink);
+
+ //
+ // Save to HOB if needed
+ //
+ if (!PcdGetBool (PcdEepromMapHobValid)) {
+ //
+ // HOB is not valid, load it into HOB.
+ //
+
+ //
+ // Toggle flag
+ //
+ PcdSetBoolS (PcdEepromMapHobValid, TRUE);
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+ScanI2cBusForImages (
+ IN UINT8 I2cBus,
+ IN OUT UINT8 **Addresses,
+ IN OUT UINT8 *AddressesSize
+ )
+{
+ BOOLEAN AddressArray[MAX_I2C_ADDRESS];
+ UINT8 AddressCount;
+ EEPROM_HEADER EepromHeader;
+ UINT8 index;
+ EFI_STATUS Status;
+
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Starting\n", __FUNCTION__, __LINE__));
+
+ //
+ // Initialize variables
+ //
+ ZeroMem (AddressArray, MAX_I2C_ADDRESS);
+ ZeroMem (&EepromHeader, sizeof (EEPROM_HEADER));
+ AddressCount = 0;
+ Status = EFI_SUCCESS;
+
+ //
+ // Sanity checks
+ //
+ if (Addresses == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Addresses buffer is NULL!\n", __FUNCTION__, __LINE__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ if (AddressesSize == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: AddressesSize buffer is NULL!\n", __FUNCTION__, __LINE__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+
+ //
+ // Make sure Addresses is empty
+ //
+ *Addresses = EepromFreePool (*Addresses);
+ *AddressesSize = 0;
+
+ //
+ // Scan bus for possible images
+ //
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Scanning bus %02x.\n", __FUNCTION__, __LINE__, I2cBus));
+ for (index = 0; index < MAX_I2C_ADDRESS; index++) {
+ //
+ // Check for somebody home
+ //
+ if (mEepromDataLibDebugFlag &&((index % 0x10) == 0)) DEBUG ((DEBUG_INFO, "."));
+ Status = I2cReadPages (I2cBus, index, 0, sizeof (EEPROM_HEADER), (UINT8 *) &EepromHeader);
+ if (!EFI_ERROR (Status) && (AsciiStrnCmp (EepromHeader.signature, "$Eeprom$", 0x08) == 0)) {
+ //
+ // Update array and count, since this devices starts with $Eeprom$
+ //
+ AddressArray[index] = TRUE;
+ AddressCount++;
+ }
+ }
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, " [%d]\n", AddressCount));
+
+ //
+ // Give return values
+ //
+ *AddressesSize = AddressCount;
+
+ //
+ // Scan array for possible images
+ //
+ if (AddressCount > 0) {
+ //
+ // Allocate return buffer
+ //
+ *Addresses = EepromAllocatePool (AddressCount);
+ if (*Addresses == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Unable to allocate buffer for Addresses!\n", __FUNCTION__, __LINE__));
+ Status = EFI_OUT_OF_RESOURCES;
+ *AddressesSize = 0;
+ goto Exit;
+ }
+ //
+ // Fill return buffer
+ //
+ for (index = MAX_I2C_ADDRESS; index > 0; index--) {
+ if (AddressArray[index - 1]) {
+ //
+ // Here's one
+ //
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Possible image on bus %02x, address %02x.\n", __FUNCTION__, __LINE__, I2cBus, index - 1));
+ (*Addresses)[--AddressCount] = index - 1;
+ if (AddressCount == 0) {
+ //
+ // We've accounted for them all. Bail.
+ //
+ Status = EFI_SUCCESS;
+ goto Exit;
+ }
+ }
+ }
+ }
+
+Exit:
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - Ending with %r\n", __FUNCTION__, __LINE__, Status));
+ }
+ return Status;
+}
+
+EEPROM_MAP_INFO *
+EFIAPI
+SearchEepromMapList (
+ IN EEPROM_PART_INFO *EepromPartInfo,
+ IN UINT8 Address,
+ IN UINT32 Offset
+ )
+{
+ EEPROM_MAP_INFO *EepromMapInfo;
+ LIST_ENTRY *Node;
+
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Starting\n", __FUNCTION__, __LINE__));
+
+ //
+ // Sanity checks
+ //
+ if (EepromPartInfo == NULL) {
+ goto Exit;
+ }
+ if ((Address > MAX_I2C_ADDRESS) && (Address != INVALID_I2C_ADDRESS)) {
+ goto Exit;
+ }
+
+ Node = GetFirstNode (&EepromPartInfo->MapHeadLink);
+ do {
+ EepromMapInfo = EEPROM_MAP_INFO_FROM_THIS (Node);
+ if (EepromMapInfo->Address == Address) {
+ //
+ // Found the right Address. Bail.
+ //
+ return EepromMapInfo;
+ }
+ if (Address == INVALID_I2C_ADDRESS) {
+ //
+ // Looking for an offset match.
+ //
+ if ((Offset >= EepromMapInfo->Offset) && (Offset < (EepromMapInfo->Offset + EepromPartInfo->BlockLength))) {
+ //
+ // Found the right offset. Bail.
+ //
+ return EepromMapInfo;
+ }
+ }
+ //
+ // Get next record
+ //
+ Node = GetNextNode (&EepromPartInfo->MapHeadLink, Node);
+ } while (!IsNull (&EepromPartInfo->MapHeadLink, Node));
+
+Exit:
+ return NULL;
+}
+
+EEPROM_PART_INFO *
+EFIAPI
+SearchEepromPartList (
+ IN UINT8 Bus,
+ IN UINT8 Address
+ )
+{
+ EEPROM_MAP_INFO *EepromMapInfo;
+ EEPROM_PART_INFO *EepromPartInfo;
+ LIST_ENTRY *Node;
+
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Starting\n", __FUNCTION__, __LINE__));
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - gEepromParts = %08x\n", __FUNCTION__, __LINE__, gEepromParts));
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - gEepromPartsHeadLink = %08x\n", __FUNCTION__, __LINE__, gEepromPartsHeadLink));
+
+ //
+ // Sanity checks
+ //
+ if ((gEepromParts == NULL) || (gEepromPartsHeadLink == NULL)) {
+ return NULL;
+ }
+ if ((Bus > MAX_I2C_BUS) || (Address > MAX_I2C_ADDRESS)) {
+ return NULL;
+ }
+
+ Node = GetFirstNode (gEepromPartsHeadLink);
+ do {
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Node = %08x\n", __FUNCTION__, __LINE__, Node));
+ EepromPartInfo = EEPROM_PART_INFO_FROM_THIS (Node);
+ if (EepromPartInfo->BusNumber == Bus) {
+ //
+ // Is this our root address?
+ //
+ if (EepromPartInfo->Address == Address) {
+ //
+ // Yep.
+ //
+ return EepromPartInfo;
+ }
+ //
+ // Found the right Bus, is it the right address?
+ //
+ EepromMapInfo = SearchEepromMapList (
+ EepromPartInfo,
+ Address,
+ 0x00000000
+ );
+ if (EepromMapInfo == NULL) {
+ //
+ // Not our record
+ //
+ } else {
+ //
+ // Found the right record. Bail.
+ //
+ return EepromPartInfo;
+ }
+ }
+ //
+ // Get next record
+ //
+ Node = GetNextNode (gEepromPartsHeadLink, Node);
+ } while (!IsNull (gEepromPartsHeadLink, Node));
+ return NULL;
+}
+
+EFI_STATUS
+EFIAPI
+WriteEepromBlockList (
+ IN UINT8 *Buffer,
+ IN VOID *FunctionInfo,
+ IN BLOCK_LIST *BlockListHead
+ )
+{
+ BLOCK_LIST *CurrentBlockList;
+ EEPROM_FUNCTION_INFO *EepromInfo;
+ LIST_ENTRY *Node;
+ UINT8 *Ptr;
+ UINT32 ReadCount;
+ EFI_STATUS Status;
+
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Starting\n", __FUNCTION__, __LINE__));
+
+ //
+ // Initialize variables
+ //
+ EepromInfo = (EEPROM_FUNCTION_INFO *) FunctionInfo;
+ ReadCount = 0;
+ Status = EFI_SUCCESS;
+
+ //
+ // Sanity checks
+ //
+ if ((Buffer == NULL) || (FunctionInfo == NULL) || (BlockListHead == NULL)) {
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+
+ //
+ // Write data from buffer
+ //
+ DEBUG ((DEBUG_INFO, "%a (#%4d) - Writing to EEPROM...\n", __FUNCTION__, __LINE__));
+ Node = GetFirstNode (&BlockListHead->Link);
+ do {
+ //
+ // Write out a block
+ //
+ CurrentBlockList = BLOCK_LIST_FROM_THIS (Node);
+ Ptr = Buffer + CurrentBlockList->Offset;
+ Status = I2cWritePages (EepromInfo->Bus, CurrentBlockList->Address, CurrentBlockList->Offset, CurrentBlockList->Size, Ptr);
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
+ //
+ // Get next record
+ //
+ Node = GetNextNode (&BlockListHead->Link, Node);
+ } while (!IsNull (&BlockListHead->Link, Node));
+
+Exit:
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - Ending with %r\n", __FUNCTION__, __LINE__, Status));
+ }
+ return Status;
+}
+
+//
+// Desc: Writes to the EEPROM and copies to the passed in buffer.
+// Variables: Offset Start copying from the offset
+// Size Size of the buffer and the number of bytes to copy
+// Buffer Storage buffer for the copied data to the EEPROM
+// FunctionInfo Pointer to function specific data
+// Return: EFI_SUCCESS Data copied successfully
+// EFI_UNSUPPORTED This function is not supported
+// EFI_INVALID_PARAMETER One of the parameters is invalid
+// EFI_NOT_READY Called before all necessary protocols available
+// EFI_DEVICE_ERROR Communication error with device
+//
+EFI_STATUS
+EFIAPI
+WriteEepromEeprom (
+ IN UINT32 Offset,
+ IN OUT UINT32 *Size,
+ IN OUT UINT8 *Buffer,
+ IN OUT VOID *FunctionInfo
+ )
+{
+ BLOCK_LIST *BlockList;
+ EEPROM_FUNCTION_INFO *EepromInfo;
+ EEPROM_PART_INFO *EepromPartInfo;
+ EFI_STATUS Status;
+
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Starting\n", __FUNCTION__, __LINE__));
+
+ //
+ // Initialize variables
+ //
+ BlockList = NULL;
+ EepromInfo = (EEPROM_FUNCTION_INFO *) FunctionInfo;
+ EepromPartInfo = NULL;
+ Status = EFI_SUCCESS;
+ LoadEepromMap ();
+
+ //
+ // Sanity checks
+ //
+ // NOTE: Input parameters already checked in wrapper function.
+ //
+ if (FunctionInfo == NULL) {
+ //
+ // This needs to be pointing to something. Bail.
+ //
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ if (EepromInfo->LibraryIndex != EEPROM_EEPROM) {
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+
+ //
+ // Grab the EEPROM map from the passed in buffer
+ //
+ EepromInfo->Buffer = Buffer;
+ EepromInfo->Size = *Size;
+ Status = FillEepromMap (FunctionInfo);
+ if (EFI_ERROR (Status)) {
+ if (Status == EFI_NO_RESPONSE) {
+ //
+ // Nobody home, bail.
+ //
+ goto Exit;
+ }
+ //
+ // We don't already have the EEPROM map in the buffer. See if there's one already in the part.
+ //
+ if (*Size == 0) {
+ //
+ // Asking for EEPROM image size. We don't know so bail.
+ //
+ Status = EFI_NOT_READY;
+ goto Exit;
+ } else {
+ EepromInfo->Buffer = NULL;
+ EepromInfo->Size = 0;
+ Status = FillEepromMap (FunctionInfo);
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
+ }
+ }
+
+ //
+ // Dump current mappings
+ //
+ DumpEepromMap ();
+
+ //
+ // Do they just want the size of the EEPROM part?
+ //
+ if (*Size == 0) {
+ //
+ // Return EEPROM part size
+ //
+ EepromPartInfo = SearchEepromPartList (EepromInfo->Bus, EepromInfo->Address);
+ if (EepromPartInfo == NULL) {
+ //
+ // Failed to find part info. Bail.
+ //
+ Status = EFI_NO_MAPPING;
+ } else {
+ //
+ // Return EEPROM part size.
+ //
+ *Size = EepromPartInfo->PartSize;
+ Status = EFI_BUFFER_TOO_SMALL;
+ }
+ goto Exit;
+ }
+
+ //
+ // Initialize block list head
+ //
+ BlockList = EepromAllocatePool (sizeof (BLOCK_LIST));
+ InitializeListHead (&BlockList->Link);
+
+ //
+ // Create list of blocks to write
+ //
+ Status = CreateBlockList (
+ Offset, // Offset in EEPROM to start writing data to
+ Size, // Number of bytes to write
+ FunctionInfo, // Pointer to function specific data
+ BlockList // Head block list
+ );
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - CreateBlockList() = %r\n", __FUNCTION__, __LINE__, Status));
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
+
+ //
+ // Write the list from the buffer
+ //
+ Status = WriteEepromBlockList (
+ Buffer,
+ FunctionInfo,
+ BlockList
+ );
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - WriteEepromBlockList() = %r\n", __FUNCTION__, __LINE__, Status));
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
+
+Exit:
+ //
+ // Free resources
+ //
+ DestroyBlockList (BlockList);
+
+ if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - Ending with %r\n", __FUNCTION__, __LINE__, Status));
+ }
+ //
+ // Save off pointers for use across LIB instances
+ //
+ SaveEepromMap ();
+
+ return Status;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/EEPROM/EepromDataEepromLib.h b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/EEPROM/EepromDataEepromLib.h
new file mode 100644
index 0000000000..931d778400
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/EEPROM/EepromDataEepromLib.h
@@ -0,0 +1,213 @@
+/** @file
+ Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
+
+ 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 _EEPROM_DATA_EEPROM_LIB_
+#define _EEPROM_DATA_EEPROM_LIB_
+////
+//// Header files
+////
+#include <Uefi.h>
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/EepromDataLib.h>
+#include <Library/PrintLib.h>
+#include <Library/TimerLib.h>
+
+#include <EepromStruct.h>
+#include "I2cLib.h"
+
+//
+// Defines
+//
+#define BLOCK_LIST_SIGNATURE SIGNATURE_32 ('B', 'k', 'L', 't')
+#define EEPROM_MAP_INFO_SIGNATURE SIGNATURE_32 ('E', 'm', 'M', 'p')
+#define EEPROM_PART_INFO_SIGNATURE SIGNATURE_32 ('E', 'm', 'P', 't')
+
+#define DEFAULT_PAGE_SIZE 0x10
+#define EEPROM_HOB_HEADER_SIGNATURE SIGNATURE_32 ('e', 'H', 'B', 'e')
+#define EEPROM_HOB_HEADER_VERSION 0x00000001
+#define EEPROM_HOB_MAX_DATA_SIZE (30 * 1024)
+
+//
+// Structures
+//
+typedef struct {
+ UINT32 Signature;
+ LIST_ENTRY Link;
+ UINT8 Address;
+ UINT16 Offset;
+ UINT32 Size;
+} BLOCK_LIST;
+
+typedef struct {
+ UINT32 Signature;
+ LIST_ENTRY Link;
+ UINT8 Address;
+ UINT32 Offset;
+} EEPROM_MAP_INFO;
+
+typedef struct {
+ UINT32 Signature;
+ UINT32 Version;
+ UINT16 BlockNumber;
+ UINT16 BlockSize;
+ UINT32 Reserved;
+} EEPROM_MEMORY_HOB_HEADER;
+
+typedef struct {
+ UINT32 Signature;
+ LIST_ENTRY Link;
+ UINT8 Address;
+ UINT32 BlockLength;
+ UINT8 BusNumber;
+ BOOLEAN Master;
+ UINT16 PageSize;
+ UINT32 PartSize;
+ UINT8 PartSpeed;
+ LIST_ENTRY MapHeadLink;
+} EEPROM_PART_INFO;
+
+//
+// Functions
+//
+EFI_STATUS
+EFIAPI
+CopyEepromMap (VOID);
+
+EFI_STATUS
+EFIAPI
+CreateBlockList (
+ IN UINT32 Offset,
+ IN UINT32 *Size,
+ IN VOID *FunctionInfo,
+ IN OUT BLOCK_LIST *BlockListHead
+ );
+
+VOID
+EFIAPI
+DestroyPageList (
+ IN BLOCK_LIST *BlockListHead
+ );
+
+VOID
+EFIAPI
+DumpEepromMap (VOID);
+
+EFI_STATUS
+EFIAPI
+FillEepromMap (
+ IN OUT VOID *FunctionInfo
+ );
+
+UINT8
+EFIAPI
+GetMapAddress (
+ IN UINT32 ReadOffset,
+ OUT UINT16 *BlockOffset,
+ IN VOID *FunctionInfo
+ );
+
+EFI_STATUS
+EFIAPI
+I2cReadPages (
+ IN UINT8 Bus,
+ IN UINT8 Address,
+ IN UINT16 Offset,
+ IN UINT32 Size,
+ IN OUT UINT8 *Buffer
+ );
+
+EFI_STATUS
+EFIAPI
+I2cWritePages (
+ IN UINT8 Bus,
+ IN UINT8 Address,
+ IN UINT16 Offset,
+ IN UINT32 Size,
+ IN OUT UINT8 *Buffer
+ );
+
+EFI_STATUS
+EFIAPI
+LoadEepromMap (VOID);
+
+EFI_STATUS
+EFIAPI
+ReadEepromBlockList (
+ IN OUT UINT8 *Buffer,
+ IN VOID *FunctionInfo,
+ IN BLOCK_LIST *BlockListHead
+ );
+
+EFI_STATUS
+EFIAPI
+SaveEepromMap (VOID);
+
+EFI_STATUS
+EFIAPI
+ScanI2cBusForImages (
+ IN UINT8 I2cBus,
+ IN OUT UINT8 **Addresses,
+ IN OUT UINT8 *AddressesSize
+ );
+
+EEPROM_MAP_INFO *
+EFIAPI
+SearchEepromMapList (
+ IN EEPROM_PART_INFO *EepromPartInfo,
+ IN UINT8 Address,
+ IN UINT32 Offset
+ );
+
+EEPROM_PART_INFO *
+EFIAPI
+SearchEepromPartList (
+ IN UINT8 Bus,
+ IN UINT8 Address
+ );
+
+EFI_STATUS
+EFIAPI
+WriteEepromBlockList (
+ IN UINT8 *Buffer,
+ IN VOID *FunctionInfo,
+ IN BLOCK_LIST *BlockListHead
+ );
+
+//
+// CR macros
+//
+#define BLOCK_LIST_FROM_THIS(a) \
+ CR (a, \
+ BLOCK_LIST, \
+ Link, \
+ BLOCK_LIST_SIGNATURE \
+ )
+
+#define EEPROM_MAP_INFO_FROM_THIS(a) \
+ CR (a, \
+ EEPROM_MAP_INFO, \
+ Link, \
+ EEPROM_MAP_INFO_SIGNATURE \
+ )
+
+#define EEPROM_PART_INFO_FROM_THIS(a) \
+ CR (a, \
+ EEPROM_PART_INFO, \
+ Link, \
+ EEPROM_PART_INFO_SIGNATURE \
+ )
+
+#endif // _EEPROM_DATA_EEPROM_LIB_
diff --git a/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/EEPROM/HobData.c b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/EEPROM/HobData.c
new file mode 100644
index 0000000000..46523dbd7b
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/EEPROM/HobData.c
@@ -0,0 +1,142 @@
+/** @file
+ Memory EEPROM raw data library instance.
+
+ Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
+
+ 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 "EepromDataEepromLib.h"
+#include <PiDxe.h>
+#include <Library/HobLib.h>
+
+EFI_STATUS
+EFIAPI
+GetEepromDataHobData (VOID)
+{
+ UINT8 *BlockData;
+ BOOLEAN BlockFound;
+ UINT16 BlockNumber;
+ UINT32 BlockSize;
+ UINT8 *Buffer;
+ EFI_HOB_GUID_TYPE *GuidHobPtr;
+ UINT16 LastBlockNumber;
+ EEPROM_MEMORY_HOB_HEADER *MemoryHobHeader;
+ EFI_STATUS Status;
+
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Starting...\n", __FUNCTION__, __LINE__));
+
+ //
+ // Initialize variables
+ //
+ Buffer = NULL;
+ Status = EFI_SUCCESS;
+
+ if (PcdGetBool (PcdEepromMemoryHobPresent)) {
+ //
+ // Clear PCD values
+ //
+ PcdSet64 (PcdEepromMemoryPointer, 0);
+ PcdSet32 (PcdEepromMemorySize, 0);
+
+ //
+ // Gather HOB data into coherent chunk by looping thru the HOBs looking for the blocks in order.
+ //
+ LastBlockNumber = 0;
+ while (TRUE) {
+ //
+ // Reset to the beginning of the HOBs
+ //
+ BlockFound = FALSE;
+ GuidHobPtr = GetFirstGuidHob (&gEepromVariableGuid);
+ while (GuidHobPtr != NULL) {
+ //
+ // Get Memory HOB header pointer
+ //
+ MemoryHobHeader = GET_GUID_HOB_DATA (GuidHobPtr);
+ BlockData = (UINT8 *) MemoryHobHeader + sizeof (EEPROM_MEMORY_HOB_HEADER);
+ BlockNumber = MemoryHobHeader->BlockNumber;
+ BlockSize = MemoryHobHeader->BlockSize;
+
+ //
+ // Is this our block?
+ //
+ if ((LastBlockNumber == BlockNumber) && (MemoryHobHeader->Signature == EEPROM_HOB_HEADER_SIGNATURE)) {
+ //
+ // Yep. Copy existing buffer to larger buffer.
+ //
+ Buffer = EepromAllocateCopyPool (PcdGet32 (PcdEepromMemorySize) + BlockSize, (UINT8 *) PcdGet64 (PcdEepromMemoryPointer));
+ if (Buffer == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Unable to allocate buffer!\n", __FUNCTION__, __LINE__));
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+
+ //
+ // Append new data
+ //
+ CopyMem (Buffer + PcdGet32 (PcdEepromMemorySize), BlockData, BlockSize);
+
+ //
+ // Free old buffer and update PCDs
+ //
+ if (PcdGet64 (PcdEepromMemoryPointer) != 0) {
+ //
+ // Buffer exists. Free it.
+ //
+ EepromFreePool ((UINT8 *) (UINTN) PcdGet64 (PcdEepromMemoryPointer));
+ }
+ BlockSize += PcdGet32 (PcdEepromMemorySize);
+ PcdSet64 (PcdEepromMemoryPointer, (UINTN) Buffer);
+ PcdSet32 (PcdEepromMemorySize, BlockSize);
+
+ //
+ // Increment counter and set flag
+ //
+ LastBlockNumber++;
+ BlockFound = TRUE;
+ break;
+ }
+
+ //
+ // Skip past present HOB to get next HOB
+ //
+ GuidHobPtr = GET_NEXT_HOB (GuidHobPtr);
+ GuidHobPtr = GetNextGuidHob (&gEepromVariableGuid, GuidHobPtr);
+ }
+ if (!BlockFound) {
+ //
+ // We're done. Bail.
+ //
+ break;
+ }
+ }
+
+ //
+ // Toggle flag.
+ //
+ PcdSetBool (PcdEepromMemoryHobPresent, FALSE);
+ }
+
+Exit:
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+SetEepromDataHobData (VOID)
+{
+ //
+ // Not supported in DXE.
+ //
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Starting...\n", __FUNCTION__, __LINE__));
+ return EFI_UNSUPPORTED;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/EEPROM/HobDataPei.c b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/EEPROM/HobDataPei.c
new file mode 100644
index 0000000000..6ee99d512e
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/EEPROM/HobDataPei.c
@@ -0,0 +1,123 @@
+/** @file
+ Memory EEPROM raw data library instance.
+
+ Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
+
+ 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 "EepromDataEepromLib.h"
+#include <PiPei.h>
+#include <Library/HobLib.h>
+
+EFI_STATUS
+EFIAPI
+GetEepromDataHobData (VOID)
+{
+ //
+ // Not supported in PEI.
+ //
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Starting...\n", __FUNCTION__, __LINE__));
+ return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+EFIAPI
+SetEepromDataHobData (VOID)
+{
+ UINT8 *BlockData;
+ UINT16 BlockNumber;
+ UINT16 BlockSize;
+ UINT8 *ImageData;
+ UINT32 ImageSize;
+ EEPROM_MEMORY_HOB_HEADER *MemoryHobHeader;
+ UINT32 Offset;
+ EFI_STATUS Status;
+
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Starting...\n", __FUNCTION__, __LINE__));
+
+ //
+ // Initialize variables
+ //
+ BlockData = NULL;
+ ImageData = (UINT8 *) (UINTN) PcdGet64 (PcdEepromMemoryPointer);
+ ImageSize = PcdGet32 (PcdEepromMemorySize);
+ Status = EFI_SUCCESS;
+
+ if (!PcdGetBool (PcdEepromMemoryHobPresent) && (ImageData != NULL) && (ImageSize != 0)) {
+ //
+ // No HOB yet. Create one.
+ //
+ BlockNumber = 0;
+ Offset = 0;
+ while (ImageSize > 0) {
+ //
+ // Adjust block size
+ //
+ if (ImageSize > EEPROM_HOB_MAX_DATA_SIZE) {
+ BlockSize = EEPROM_HOB_MAX_DATA_SIZE;
+ } else {
+ BlockSize = (UINT16) ImageSize;
+ }
+
+ //
+ // Create Block data buffer
+ //
+ BlockData = EepromFreePool (BlockData);
+ BlockData = EepromAllocatePool (BlockSize + sizeof (EEPROM_MEMORY_HOB_HEADER));
+ if (BlockData == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Unable to allocate buffer!\n", __FUNCTION__, __LINE__));
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+
+ //
+ // Setup header
+ //
+ MemoryHobHeader = (EEPROM_MEMORY_HOB_HEADER *) BlockData;
+ MemoryHobHeader->Signature = EEPROM_HOB_HEADER_SIGNATURE;
+ MemoryHobHeader->Version = EEPROM_HOB_HEADER_VERSION;
+ MemoryHobHeader->BlockNumber = BlockNumber;
+ MemoryHobHeader->BlockSize = BlockSize;
+ MemoryHobHeader->Reserved = 0x00000000;
+
+ //
+ // Copy data into buffer
+ //
+ CopyMem (
+ (BlockData + sizeof (EEPROM_MEMORY_HOB_HEADER)),
+ (ImageData + Offset),
+ (BlockSize + sizeof (EEPROM_MEMORY_HOB_HEADER))
+ );
+
+ //
+ // Create GUID HOB
+ //
+ BuildGuidDataHob (&gEepromVariableGuid, BlockData, BlockSize);
+
+ //
+ // Adjust pointers and such
+ //
+ Offset += BlockSize;
+ BlockNumber += 1;
+ ImageSize -= BlockSize;
+ }
+
+ //
+ // Toggle flag.
+ //
+ PcdSetBool (PcdEepromMemoryHobPresent, TRUE);
+ }
+
+Exit:
+ BlockData = EepromFreePool (BlockData);
+ return Status;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/EEPROM/I2cLib.c b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/EEPROM/I2cLib.c
new file mode 100644
index 0000000000..32f9d3f7e4
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/EEPROM/I2cLib.c
@@ -0,0 +1,1164 @@
+/** @file
+ I2C library instance.
+
+ Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.<BR>
+
+ 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 "I2cLib.h"
+
+//
+// List of I2C controllers
+//
+LPSS_PCI_DEVICE_INFO mLpssPciDeviceList[] = {
+ {0, DEFAULT_PCI_BUS_NUMBER_SC, PCI_DEVICE_NUMBER_LPSS_I2C0, PCI_FUNCTION_NUMBER_LPSS_I2C0, LPSS_I2C0_TMP_BAR0 + (LPSS_I2C_TMP_BAR0_DELTA*0), LPSS_I2C0_TMP_BAR0 + (LPSS_I2C_TMP_BAR0_DELTA*0) + LPSS_I2C_TMP_BAR1_OFFSET},
+ {0, DEFAULT_PCI_BUS_NUMBER_SC, PCI_DEVICE_NUMBER_LPSS_I2C0, PCI_FUNCTION_NUMBER_LPSS_I2C1, LPSS_I2C0_TMP_BAR0 + (LPSS_I2C_TMP_BAR0_DELTA*1), LPSS_I2C0_TMP_BAR0 + (LPSS_I2C_TMP_BAR0_DELTA*1) + LPSS_I2C_TMP_BAR1_OFFSET},
+ {0, DEFAULT_PCI_BUS_NUMBER_SC, PCI_DEVICE_NUMBER_LPSS_I2C0, PCI_FUNCTION_NUMBER_LPSS_I2C2, LPSS_I2C0_TMP_BAR0 + (LPSS_I2C_TMP_BAR0_DELTA*2), LPSS_I2C0_TMP_BAR0 + (LPSS_I2C_TMP_BAR0_DELTA*2) + LPSS_I2C_TMP_BAR1_OFFSET},
+ {0, DEFAULT_PCI_BUS_NUMBER_SC, PCI_DEVICE_NUMBER_LPSS_I2C0, PCI_FUNCTION_NUMBER_LPSS_I2C3, LPSS_I2C0_TMP_BAR0 + (LPSS_I2C_TMP_BAR0_DELTA*3), LPSS_I2C0_TMP_BAR0 + (LPSS_I2C_TMP_BAR0_DELTA*3) + LPSS_I2C_TMP_BAR1_OFFSET},
+ {0, DEFAULT_PCI_BUS_NUMBER_SC, PCI_DEVICE_NUMBER_LPSS_I2C1, PCI_FUNCTION_NUMBER_LPSS_I2C4, LPSS_I2C0_TMP_BAR0 + (LPSS_I2C_TMP_BAR0_DELTA*4), LPSS_I2C0_TMP_BAR0 + (LPSS_I2C_TMP_BAR0_DELTA*4) + LPSS_I2C_TMP_BAR1_OFFSET},
+ {0, DEFAULT_PCI_BUS_NUMBER_SC, PCI_DEVICE_NUMBER_LPSS_I2C1, PCI_FUNCTION_NUMBER_LPSS_I2C5, LPSS_I2C0_TMP_BAR0 + (LPSS_I2C_TMP_BAR0_DELTA*5), LPSS_I2C0_TMP_BAR0 + (LPSS_I2C_TMP_BAR0_DELTA*5) + LPSS_I2C_TMP_BAR1_OFFSET},
+ {0, DEFAULT_PCI_BUS_NUMBER_SC, PCI_DEVICE_NUMBER_LPSS_I2C1, PCI_FUNCTION_NUMBER_LPSS_I2C6, LPSS_I2C0_TMP_BAR0 + (LPSS_I2C_TMP_BAR0_DELTA*6), LPSS_I2C0_TMP_BAR0 + (LPSS_I2C_TMP_BAR0_DELTA*6) + LPSS_I2C_TMP_BAR1_OFFSET},
+ {0, DEFAULT_PCI_BUS_NUMBER_SC, PCI_DEVICE_NUMBER_LPSS_I2C1, PCI_FUNCTION_NUMBER_LPSS_I2C7, LPSS_I2C0_TMP_BAR0 + (LPSS_I2C_TMP_BAR0_DELTA*7), LPSS_I2C0_TMP_BAR0 + (LPSS_I2C_TMP_BAR0_DELTA*7) + LPSS_I2C_TMP_BAR1_OFFSET}
+};
+#define LPSS_PCI_DEVICE_NUMBER (sizeof (mLpssPciDeviceList) / sizeof (LPSS_PCI_DEVICE_INFO))
+
+//
+// List of I2C controller clock values
+//
+LPSS_I2C_CLOCK_SCL_INFO mLPSS_I2C_CLOCK_SCL_INFO[] = {
+ {0x244, 0x2D0, 0x64, 0xC8, 0x06, 0x13},
+ {0x244, 0x2D0, 0x64, 0xC8, 0x06, 0x13},
+ {0x244, 0x2D0, 0x64, 0xC8, 0x06, 0x13},
+ {0x244, 0x2DA, 0x1E, 0x3C, 0x06, 0x13},
+ {0x244, 0x2DA, 0x1E, 0x50, 0x06, 0x13},
+ {0x244, 0x2D0, 0x69, 0xC8, 0x06, 0x13},
+ {0x244, 0x2D0, 0x69, 0xC8, 0x06, 0x13},
+ {0x244, 0x2D0, 0x70, 0xC8, 0x06, 0x13}
+};
+#define LPSS_I2C_CLOCK_SCL_INFO_NUMBER (sizeof (mLPSS_I2C_CLOCK_SCL_INFO) / sizeof (LPSS_I2C_CLOCK_SCL_INFO))
+
+//
+// List of I2C controller PAD settings
+//
+BXT_GPIO_PAD_INIT mLPSS_PAD_INFO[] = {
+ BXT_GPIO_PAD_CONF (L"GPIO_124 LPSS_I2C0_SDA", M1, NA, NA, NA, NA, Wake_Disabled, P_20K_H, NA, NA, D1RxDRx1I, EnPu, GPIO_PADBAR + 0x0000, WEST),
+ BXT_GPIO_PAD_CONF (L"GPIO_125 LPSS_I2C0_SCL", M1, NA, NA, NA, NA, Wake_Disabled, P_20K_H, NA, NA, D1RxDRx1I, EnPu, GPIO_PADBAR + 0x0008, WEST),
+ BXT_GPIO_PAD_CONF (L"GPIO_126 LPSS_I2C1_SDA", M1, NA, NA, NA, NA, Wake_Disabled, P_20K_H, NA, NA, D1RxDRx1I, EnPu, GPIO_PADBAR + 0x0010, WEST),
+ BXT_GPIO_PAD_CONF (L"GPIO_127 LPSS_I2C1_SCL", M1, NA, NA, NA, NA, Wake_Disabled, P_20K_H, NA, NA, D1RxDRx1I, EnPu, GPIO_PADBAR + 0x0018, WEST),
+ BXT_GPIO_PAD_CONF (L"GPIO_128 LPSS_I2C2_SDA", M1, NA, NA, NA, NA, Wake_Disabled, P_20K_H, NA, NA, D1RxDRx1I, EnPu, GPIO_PADBAR + 0x0020, WEST),
+ BXT_GPIO_PAD_CONF (L"GPIO_129 LPSS_I2C2_SCL", M1, NA, NA, NA, NA, Wake_Disabled, P_20K_H, NA, NA, D1RxDRx1I, EnPu, GPIO_PADBAR + 0x0028, WEST),
+ BXT_GPIO_PAD_CONF (L"GPIO_130 LPSS_I2C3_SDA", M1, NA, NA, NA, NA, Wake_Disabled, P_20K_H, NA, NA, D1RxDRx1I, EnPu, GPIO_PADBAR + 0x0030, WEST),
+ BXT_GPIO_PAD_CONF (L"GPIO_131 LPSS_I2C3_SCL", M1, NA, NA, NA, NA, Wake_Disabled, P_20K_H, NA, NA, D1RxDRx1I, EnPu, GPIO_PADBAR + 0x0038, WEST),
+ BXT_GPIO_PAD_CONF (L"GPIO_132 LPSS_I2C4_SDA", M1, NA, NA, NA, NA, Wake_Disabled, P_20K_H, NA, NA, D1RxDRx1I, EnPu, GPIO_PADBAR + 0x0040, WEST),
+ BXT_GPIO_PAD_CONF (L"GPIO_133 LPSS_I2C4_SCL", M1, NA, NA, NA, NA, Wake_Disabled, P_20K_H, NA, NA, D1RxDRx1I, EnPu, GPIO_PADBAR + 0x0048, WEST),
+ BXT_GPIO_PAD_CONF (L"GPIO_134 LPSS_I2C5_SDA", M1, NA, NA, NA, NA, Wake_Disabled, P_20K_H, NA, NA, D1RxDRx1I, EnPu, GPIO_PADBAR + 0x0050, WEST),
+ BXT_GPIO_PAD_CONF (L"GPIO_135 LPSS_I2C5_SCL", M1, NA, NA, NA, NA, Wake_Disabled, P_20K_H, NA, NA, D1RxDRx1I, EnPu, GPIO_PADBAR + 0x0058, WEST),
+ BXT_GPIO_PAD_CONF (L"GPIO_136 LPSS_I2C6_SDA", M1, NA, NA, NA, NA, Wake_Disabled, P_20K_H, NA, NA, D1RxDRx1I, EnPu, GPIO_PADBAR + 0x0060, WEST),
+ BXT_GPIO_PAD_CONF (L"GPIO_137 LPSS_I2C6_SCL", M1, NA, NA, NA, NA, Wake_Disabled, P_20K_H, NA, NA, D1RxDRx1I, EnPu, GPIO_PADBAR + 0x0068, WEST),
+ BXT_GPIO_PAD_CONF (L"GPIO_138 LPSS_I2C7_SDA", M1, NA, NA, NA, NA, Wake_Disabled, P_20K_H, NA, NA, D0RxDRx0I, EnPu, GPIO_PADBAR + 0x0070, WEST),
+ BXT_GPIO_PAD_CONF (L"GPIO_139 LPSS_I2C7_SCL", M1, NA, NA, NA, NA, Wake_Disabled, P_20K_H, NA, NA, D0RxDRx0I, EnPu, GPIO_PADBAR + 0x0078, WEST)
+};
+
+BOOLEAN gI2cDebugFlag = FALSE;
+
+////
+//// Internal I2C functions
+////
+//
+// Desc: Clears the interrupts on this I2C controller
+// Input: I2cBaseAddress - Pointer to the MMIO base address for the I2C controller
+// Output: NA
+//
+VOID
+I2cClearInterrupts (
+ IN UINT32 I2cBaseAddress
+ )
+{
+ MmioRead32 (I2cBaseAddress + R_IC_CLR_INTR);
+ return;
+}
+
+//
+// Desc: Clears the TX Abort on this I2C controller
+// Input: I2cBaseAddress - Pointer to the MMIO base address for the I2C controller
+// Output: NA
+//
+VOID
+I2cClearTxAbort (
+ IN UINT32 I2cBaseAddress
+ )
+{
+ MmioRead32 (I2cBaseAddress + R_IC_CLR_TX_ABRT);
+ return;
+}
+
+//
+// Desc: Disable this I2C controller
+// Input: I2cBaseAddress - Pointer to the MMIO base address for the I2C controller
+// Output: Status - EFI_SUCCESS - I2C host controller is completely inactive
+// EFI_NOT_READY - I2C host controller is still in an enabled state
+//
+EFI_STATUS
+I2cDisable (
+ IN UINT32 I2cBaseAddress
+ )
+{
+ UINT32 NumTries;
+ EFI_STATUS Status;
+
+ //
+ // Initialize variables
+ //
+ Status = EFI_SUCCESS;
+
+ //
+ // Disable I2C controller
+ //
+ MmioWrite32 (I2cBaseAddress + R_IC_ENABLE, 0);
+ NumTries = 10000; // 0.1 seconds
+ while (0 != (MmioRead32 (I2cBaseAddress + R_IC_ENABLE_STATUS) & 0x03)) {
+ MicroSecondDelay (10);
+ NumTries --;
+ if (0 == NumTries) {
+ Status = EFI_NOT_READY;
+ goto Exit;
+ }
+ }
+
+Exit:
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - Ending with %r\n", __FUNCTION__, __LINE__, Status));
+ }
+ return Status;
+}
+
+/**
+ Enable I2C host controller
+
+ @param[in] I2CBaseAddress - BAR0 address of I2C host controller
+
+ @retval EFI_SUCCESS - I2C host controller is in an enabled state.
+ @retval EFI_NOT_READY - I2C host controller is still inactive.
+**/
+EFI_STATUS
+I2cEnable (
+ IN UINT32 I2cBaseAddress
+ )
+{
+ UINT32 NumTries;
+ EFI_STATUS Status;
+
+ //
+ // Initialize variables
+ //
+ NumTries = 10000; // 0.1 seconds
+ Status = EFI_SUCCESS;
+
+ //
+ // Enable I2C controller
+ //
+ MmioWrite32 (I2cBaseAddress + R_IC_ENABLE, I2C_ENABLE_ENABLE);
+ while (I2C_ENABLE_ENABLE != (MmioRead32 (I2cBaseAddress + R_IC_ENABLE_STATUS) & I2C_ENABLE_ENABLE)) {
+ MicroSecondDelay (10);
+ NumTries --;
+ if (0 == NumTries) {
+ Status = EFI_NOT_READY;
+ goto Exit;
+ }
+ }
+
+Exit:
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - Ending with %r\n", __FUNCTION__, __LINE__, Status));
+ }
+ return Status;
+}
+
+UINT16
+I2cGetTxAbortStatus (
+ IN UINT32 I2cBaseAddress
+ )
+{
+ UINT16 TxAbortStatus;
+
+ if (I2cBaseAddress == 0) {
+ TxAbortStatus = 0xFFFF;
+ } else {
+ TxAbortStatus = (UINT16) (MmioRead32 (I2cBaseAddress + R_IC_TX_ABRT_SOURCE) & 0xFFFF);
+ }
+ return TxAbortStatus;
+}
+
+/**
+ Get I2C controller raw interrupt status
+
+ @param[in] I2CBaseAddress - BAR0 address of I2C host controller
+
+ @retval UINT16 - Raw interrupt status bit flags
+**/
+UINT16
+I2cGetRawStatus (
+ IN UINT32 I2cBaseAddress
+ )
+{
+ UINT16 RawStatus;
+
+ if (I2cBaseAddress == 0) {
+ RawStatus = 0xFFFF;
+ } else {
+ RawStatus = (UINT16) (MmioRead32 (I2cBaseAddress + R_IC_RAW_INTR_STAT) & 0x3FFF);
+ }
+
+ return RawStatus;
+}
+
+/**
+ Get I2C controller RX FIFO count
+
+ @param[in] I2CBaseAddress - BAR0 address of I2C host controller
+
+ @retval UINT16 - RX FIFO count
+**/
+UINT16
+I2cGetRxFifo (
+ IN UINT32 I2cBaseAddress
+ )
+{
+ UINT16 RxFifo;
+
+ if (I2cBaseAddress == 0) {
+ RxFifo = 0xFFFF;
+ } else {
+ RxFifo = (UINT16) (MmioRead32 (I2cBaseAddress + R_IC_RXFLR) & 0x01FF);
+ }
+
+ return RxFifo;
+}
+
+/**
+ Get I2C controller status
+
+ @param[in] I2CBaseAddress - BAR0 address of I2C host controller
+
+ @retval UINT16 - Status bit flags
+**/
+UINT16
+I2cGetStatus (
+ IN UINT32 I2cBaseAddress
+ )
+{
+ UINT16 I2cStatus;
+
+ if (I2cBaseAddress == 0) {
+ I2cStatus = 0xFFFF;
+ } else {
+ I2cStatus = (UINT16) (MmioRead32 (I2cBaseAddress + R_IC_STATUS) & 0x007F);
+ }
+
+ return I2cStatus;
+}
+
+/**
+ Get I2C controller TX FIFO count
+
+ @param[in] I2CBaseAddress - BAR0 address of I2C host controller
+
+ @retval UINT16 - TX FIFO count
+**/
+UINT16
+I2cGetTxFifo (
+ IN UINT32 I2cBaseAddress
+ )
+{
+ UINT16 TxFifo;
+
+ if (I2cBaseAddress == 0) {
+ TxFifo = 0xFFFF;
+ } else {
+ TxFifo = (UINT16) (MmioRead32 (I2cBaseAddress + R_IC_TXFLR) & 0x01FF);
+ }
+
+ return TxFifo;
+}
+
+EFI_STATUS
+I2cProgramPad (
+ IN UINT8 Bus
+ )
+{
+ UINT8 index;
+ EFI_STATUS Status;
+
+ if (gI2cDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Programming PADs for bus #%d\n", __FUNCTION__, __LINE__, Bus));
+
+ //
+ // Initialize variables
+ //
+ Status = EFI_SUCCESS;
+
+ //
+ // Sanity checks
+ //
+ if (Bus > MAX_I2C_BUS) {
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+
+ //
+ // Program SDA/SCL
+ //
+ for (index = 0; index < 2; index++) {
+ if (gI2cDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Programming PAD %s\n", __FUNCTION__, __LINE__, mLPSS_PAD_INFO[(Bus * 2) + index].pad_name));
+ GpioPadConfigTable (1, &mLPSS_PAD_INFO[(Bus * 2) + index]);
+ }
+
+ //
+ // Pause a bit
+ //
+ MicroSecondDelay (EEPROM_ROUTINE_DELAY);
+
+Exit:
+ return Status;
+}
+
+/**
+ Set the I2C controller bus clock frequency.
+
+ The software and controller do a best case effort of using the specified
+ frequency for the I2C bus. If the frequency does not match exactly then
+ the controller will use a slightly lower frequency for the I2C to avoid
+ exceeding the operating conditions for any of the I2C devices on the bus.
+ For example if 400 KHz was specified and the controller's divide network
+ only supports 402 KHz or 398 KHz then the controller would be set to 398
+ KHz. However if the desired frequency is 400 KHz and the controller only
+ supports 1 MHz and 100 KHz then this routine would return EFI_UNSUPPORTED.
+
+ @param[in] Bus - I2C Bus number to which the I2C device has been connected
+ @param[in] I2CBaseAddress - BAR0 address of I2C host controller
+
+ @retval EFI_SUCCESS - The bus frequency was set successfully.
+**/
+EFI_STATUS
+I2cSetBusFrequency (
+ IN UINT8 Bus,
+ IN UINT32 I2cBaseAddress
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Initialize variables
+ //
+ Status = EFI_SUCCESS;
+
+ if (gI2cDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - I2cBusFrequencySet bus: %d\n", __FUNCTION__, __LINE__, Bus));
+ ASSERT ((Bus < LPSS_I2C_CLOCK_SCL_INFO_NUMBER));
+ //
+ // Set the 100 KHz clock divider according to SV result and I2C spec
+ //
+ MmioWrite32 (I2cBaseAddress + R_IC_SS_SCL_HCNT, (UINT16) mLPSS_I2C_CLOCK_SCL_INFO[Bus].SS_SCL_HCNT);
+ MmioWrite32 (I2cBaseAddress + R_IC_SS_SCL_LCNT, (UINT16) mLPSS_I2C_CLOCK_SCL_INFO[Bus].SS_SCL_LCNT);
+ if (gI2cDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - I2cBusFrequencySet R_IC_SS_SCL_HCNT: 0x%08X, R_IC_SS_SCL_LCNT: 0x%08X\r\n",
+ __FUNCTION__,
+ __LINE__,
+ MmioRead32 (I2cBaseAddress + R_IC_SS_SCL_HCNT),
+ MmioRead32 (I2cBaseAddress + R_IC_SS_SCL_LCNT)));
+ //
+ // Set the 400 KHz clock divider according to SV result and I2C spec
+ //
+ MmioWrite32 (I2cBaseAddress + R_IC_FS_SCL_HCNT, (UINT16) mLPSS_I2C_CLOCK_SCL_INFO[Bus].FS_SCL_HCNT);
+ MmioWrite32 (I2cBaseAddress + R_IC_FS_SCL_LCNT, (UINT16) mLPSS_I2C_CLOCK_SCL_INFO[Bus].FS_SCL_LCNT);
+ if (gI2cDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - I2cBusFrequencySet R_IC_FS_SCL_HCNT: 0x%08X, R_IC_FS_SCL_LCNT: 0x%08X\r\n",
+ __FUNCTION__,
+ __LINE__,
+ MmioRead32 (I2cBaseAddress + R_IC_FS_SCL_HCNT),
+ MmioRead32 (I2cBaseAddress + R_IC_FS_SCL_LCNT)));
+ //
+ // Set the 3.4MHz clock divider according to SV result and I2C spec
+ //
+ MmioWrite32 (I2cBaseAddress + R_IC_HS_SCL_HCNT, (UINT16)mLPSS_I2C_CLOCK_SCL_INFO[Bus].HS_SCL_HCNT);
+ MmioWrite32 (I2cBaseAddress + R_IC_HS_SCL_LCNT, (UINT16)mLPSS_I2C_CLOCK_SCL_INFO[Bus].HS_SCL_LCNT);
+ if (gI2cDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - I2cBusFrequencySet R_IC_HS_SCL_HCNT: 0x%08X, R_IC_HS_SCL_LCNT: 0x%08X\r\n",
+ __FUNCTION__,
+ __LINE__,
+ MmioRead32 (I2cBaseAddress + R_IC_HS_SCL_HCNT),
+ MmioRead32 (I2cBaseAddress + R_IC_HS_SCL_LCNT)));
+
+ //
+ // Set hold register
+ //
+ MmioWrite32 (I2cBaseAddress + R_IC_SDA_HOLD, (UINT16) 0x06);
+ if (gI2cDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - I2cBusFrequencySet R_IC_SDA_HOLD: 0x%08X\r\n", __FUNCTION__, __LINE__, MmioRead32 (I2cBaseAddress + R_IC_SDA_HOLD)));
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - Ending with %r\n", __FUNCTION__, __LINE__, Status));
+ }
+ return Status;
+}
+
+/**
+ Program LPSS I2C PCI controller's BAR0 and enable memory decode.
+
+ @param[in] Bus - I2C Bus number to which the I2C device has been connected
+
+ @retval EFI_SUCCESS - I2C controller's BAR0 is programmed and memory decode enabled.
+ @retval EFI_NOT_READY - I2C controller's is not exist or its function has been disabled.
+ @retval EFI_DEVICE_ERROR - I2C controller can't be enabled.
+**/
+EFI_STATUS
+ProgramPciLpssI2C (
+ IN UINT8 Bus
+ )
+{
+ UINT32 Data32;
+ UINT32 I2CBar0;
+ UINT32 I2CBar1;
+ UINTN PciMmBase;
+ UINT32 PmcBase;
+ EFI_STATUS Status;
+ UINT32 I2cPortDisable[] = {
+ B_PMC_FUNC_DIS_LPSS_I2C0,
+ B_PMC_FUNC_DIS_LPSS_I2C1,
+ B_PMC_FUNC_DIS_LPSS_I2C2,
+ B_PMC_FUNC_DIS_LPSS_I2C3,
+ B_PMC_FUNC_DIS_LPSS_I2C4,
+ B_PMC_FUNC_DIS_LPSS_I2C5,
+ B_PMC_FUNC_DIS_LPSS_I2C6,
+ B_PMC_FUNC_DIS_LPSS_I2C7
+ };
+
+ //
+ // Initialize variables
+ //
+ PciMmBase = 0;
+ Status = EFI_SUCCESS;
+
+ //
+ // Set PADs to I2C mode
+ //
+ I2cProgramPad (Bus);
+
+ //
+ // Check PMC disable register
+ //
+ PmcBase = PMC_BASE_ADDRESS;
+ Data32 = MmioRead32 (PmcBase + R_PMC_FUNC_DIS);
+
+ if (Data32 == 0xFFFFFFFF) {
+ if (gI2cDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - ProgramPciLpssI2C() PMC disable register not available. [%08x]\n", __FUNCTION__, __LINE__, PMC_BASE_ADDRESS));
+ } else {
+ if ((Data32 & I2cPortDisable[Bus]) != 0) {
+ // This I2C port is disabled. Turn it on.
+ Data32 &= ~I2cPortDisable[Bus];
+ MmioWrite32 (PmcBase + R_PMC_FUNC_DIS, Data32);
+ if (gI2cDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - ProgramPciLpssI2C() enable I2C controller #%x\n", __FUNCTION__, __LINE__, Bus));
+ // Make sure it took.
+ if (Data32 != MmioRead32 (PmcBase + R_PMC_FUNC_DIS)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ProgramPciLpssI2C() failed to enable I2C controller #%x [%08x:%08x]\n",
+ __FUNCTION__,
+ __LINE__,
+ Bus,
+ Data32,
+ MmioRead32 (PmcBase + R_PMC_FUNC_DIS)));
+ Status = EFI_DEVICE_ERROR;
+ goto Exit;
+ }
+ }
+ }
+
+ if (gI2cDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - ProgramPciLpssI2C()------------BusNo=%x\n", __FUNCTION__, __LINE__, Bus));
+
+ PciMmBase = MmPciAddress (
+ mLpssPciDeviceList[Bus].Segment,
+ mLpssPciDeviceList[Bus].BusNum,
+ mLpssPciDeviceList[Bus].DeviceNum,
+ mLpssPciDeviceList[Bus].FunctionNum,
+ 0
+ );
+ if (gI2cDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Program Pci Lpss I2C Device %x %x %x PciMmBase:%x\n",
+ __FUNCTION__,
+ __LINE__,
+ mLpssPciDeviceList[Bus].BusNum,
+ mLpssPciDeviceList[Bus].DeviceNum,
+ mLpssPciDeviceList[Bus].FunctionNum, PciMmBase));
+
+ //
+ // Check if device present
+ //
+ if (MmioRead32 (PciMmBase) != 0xFFFFFFFF) {
+ if ((MmioRead32 (PciMmBase + R_LPSS_IO_STSCMD) & B_LPSS_IO_STSCMD_MSE)) {
+ //
+ // In Pei stage, we always disable Bus master, and memory space enabling for BAR re-programming
+ // In DXE stage, will read existing BAR value instead of re-programming
+ //
+ I2CBar0 = MmioRead32 (PciMmBase + R_LPSS_IO_BAR) & B_LPSS_IO_BAR_BA;
+ I2CBar1 = MmioRead32 (PciMmBase + R_LPSS_IO_BAR1) & B_LPSS_IO_BAR_BA;
+ if ((I2CBar0 != (UINT32) mLpssPciDeviceList[Bus].Bar0) || (I2CBar1 != (UINT32) mLpssPciDeviceList[Bus].Bar1)) {
+ mLpssPciDeviceList[Bus].Bar0 = MmioRead32 (PciMmBase + R_LPSS_IO_BAR) & B_LPSS_IO_BAR_BA; // get the address allocated.
+ mLpssPciDeviceList[Bus].Bar1 = MmioRead32 (PciMmBase + R_LPSS_IO_BAR1) & B_LPSS_IO_BAR_BA;
+ if (gI2cDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Get bar0:0x%x bar1:0x%x\n",
+ __FUNCTION__,
+ __LINE__,
+ mLpssPciDeviceList[Bus].Bar0,
+ mLpssPciDeviceList[Bus].Bar1));
+ }
+ } else {
+ //
+ // Program BAR 0
+ //
+ ASSERT (((mLpssPciDeviceList[Bus].Bar0 & B_LPSS_IO_BAR_BA) == mLpssPciDeviceList[Bus].Bar0) && (mLpssPciDeviceList[Bus].Bar0 != 0));
+ MmioWrite32 ((UINTN) (PciMmBase + R_LPSS_IO_BAR), (UINT32) (mLpssPciDeviceList[Bus].Bar0 & B_LPSS_IO_BAR_BA));
+ //
+ // Program BAR 1
+ //
+ ASSERT (((mLpssPciDeviceList[Bus].Bar1 & B_LPSS_IO_BAR1_BA) == mLpssPciDeviceList[Bus].Bar1) && (mLpssPciDeviceList[Bus].Bar1 != 0));
+ MmioWrite32 ((UINTN) (PciMmBase + R_LPSS_IO_BAR1), (UINT32) (mLpssPciDeviceList[Bus].Bar1 & B_LPSS_IO_BAR1_BA));
+ //
+ // Bus Master Enable & Memory Space Enable
+ //
+ MmioOr32 ((UINTN) (PciMmBase + R_LPSS_IO_STSCMD), (UINT32) (B_LPSS_IO_STSCMD_BME | B_LPSS_IO_STSCMD_MSE));
+ ASSERT (MmioRead32 (mLpssPciDeviceList[Bus].Bar0) != 0xFFFFFFFF);
+ }
+
+ //
+ // Release Resets
+ //
+ MmioWrite32 (mLpssPciDeviceList[Bus].Bar0 + R_LPSS_IO_MEM_RESETS, B_LPSS_IO_MEM_HC_RESET_REL | B_LPSS_IO_MEM_iDMA_RESET_REL);
+
+ if (gI2cDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - ProgramPciLpssI2C() Programmed()\n", __FUNCTION__, __LINE__));
+ Status = EFI_SUCCESS;
+ goto Exit;
+ } else {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - Pci Lpss I2C Device %x %x %x does not exist!\n",
+ __FUNCTION__,
+ __LINE__,
+ mLpssPciDeviceList[Bus].BusNum,
+ mLpssPciDeviceList[Bus].DeviceNum,
+ mLpssPciDeviceList[Bus].FunctionNum));
+
+ Status = EFI_NOT_READY;
+ goto Exit;
+ }
+
+Exit:
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - Ending with %r\n", __FUNCTION__, __LINE__, Status));
+ }
+ return Status;
+}
+
+////
+//// Public I2C functions
+////
+//
+// Desc: Initializes the controller and returns the MMIO base address
+// Input: Bus - I2C controller, 0 based
+// Address - 7-bit slave address
+// Speed - Uses the I2C_SPEED enum to set the controller speed
+// I2cBaseAddress - Pointer to the MMIO base address for the I2C controller
+// Output: EFI_SUCCESS - Initialization completed successfully
+// EFI_DEVICE_ERROR - I2C controller error
+// EFI_INVALID_PARAMETER - Invalid input parameter
+//
+EFI_STATUS
+I2cInit (
+ IN UINT8 Bus,
+ IN UINT16 Address,
+ IN UINT8 Speed,
+ IN OUT UINT32 *I2cBaseAddress
+ )
+{
+ UINT32 BaseAddress;
+ UINTN PciMmBase;
+ EFI_STATUS Status;
+
+ //
+ // Sanity checks
+ //
+ if (Bus > MAX_I2C_BUS) {
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ if (Address > MAX_I2C_ADDRESS) {
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ if (Speed > Max_Speed) {
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ if (I2cBaseAddress == NULL) {
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+
+ //
+ // Initialize variables
+ //
+ *I2cBaseAddress = 0;
+
+ //
+ // Get current MMIO base address
+ //
+ PciMmBase = MmPciAddress (
+ mLpssPciDeviceList[Bus].Segment,
+ mLpssPciDeviceList[Bus].BusNum,
+ mLpssPciDeviceList[Bus].DeviceNum,
+ mLpssPciDeviceList[Bus].FunctionNum,
+ 0
+ );
+ BaseAddress = MmioRead32 (PciMmBase + R_LPSS_IO_BAR) & B_LPSS_IO_BAR_BA;
+ if (gI2cDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - I2CBaseAddress = 0x%08x:0x%08x \n", __FUNCTION__, __LINE__, BaseAddress, (UINT32) mLpssPciDeviceList[Bus].Bar0));
+
+ //
+ // Skip reinit if targeting the same I2C bus
+ //
+ if (BaseAddress == (UINT32) mLpssPciDeviceList[Bus].Bar0) {
+ MmioWrite32 (BaseAddress + R_IC_TAR, Address);
+ *I2cBaseAddress = BaseAddress;
+ Status = EFI_SUCCESS;
+ goto Exit;
+ }
+
+ //
+ // Program I2C controller
+ //
+ Status = ProgramPciLpssI2C (Bus);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ProgramPciLpssI2C failed! %r\n", __FUNCTION__, __LINE__, Status));
+ goto Exit;
+ }
+
+ //
+ // Retrieve I2C MMIO base address
+ //
+ BaseAddress = (UINT32) mLpssPciDeviceList[Bus].Bar0;
+ if (gI2cDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - I2CBaseAddress = 0x%x \n", __FUNCTION__, __LINE__, BaseAddress));
+
+ //
+ // Reset controller
+ //
+ Status = I2cReset (BaseAddress, Bus, Address, Speed);
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
+
+ //
+ // Pause a bit
+ //
+ MicroSecondDelay (EEPROM_ROUTINE_DELAY);
+
+ //
+ // Pass out MMIO base
+ //
+ *I2cBaseAddress = BaseAddress;
+ Status = EFI_SUCCESS;
+
+Exit:
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - Ending with %r\n", __FUNCTION__, __LINE__, Status));
+ }
+ return Status;
+}
+
+//
+// Desc: Polls the I2C controller with reads until it responds.
+// Input: I2cBaseAddress - Pointer to the MMIO base address for the I2C controller
+// Output: EFI_SUCCESS - Initialization completed successfully
+// EFI_DEVICE_ERROR - I2C controller error
+//
+EFI_STATUS
+I2cPoll (
+ IN UINT32 I2cBaseAddress
+ )
+{
+ EFI_STATUS Status;
+ UINT16 Timeout;
+ UINT8 Value;
+
+ //
+ // Use a read to poll the slave
+ //
+ Status = EFI_DEVICE_ERROR;
+ Timeout = 0;
+ while (EFI_ERROR (Status) && Timeout < 1000) {
+ MicroSecondDelay (10);
+ Status = I2cRead (I2cBaseAddress, &Value, TRUE, TRUE);
+ Timeout++;
+ }
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - Ending with %r\n", __FUNCTION__, __LINE__, Status));
+ }
+ return Status;
+}
+
+//
+// Desc: Read a byte from the I2C controller
+// Input: I2cBaseAddress - MMIO base address for the I2C controller
+// Data - Pointer to where to store the data
+// Start - Send start bit?
+// End - Send end bit?
+// Output: EFI_SUCCESS - Read completed successfully
+// EFI_DEVICE_ERROR - I2C controller error
+// EFI_INVALID_PARAMETER - Invalid input parameter
+//
+EFI_STATUS
+I2cRead (
+ IN UINT32 I2cBaseAddress,
+ IN OUT UINT8 *Data,
+ IN BOOLEAN Start,
+ IN BOOLEAN End
+ )
+{
+ UINT32 Data32;
+ EFI_STATUS Status;
+
+ if (gI2cDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Starting\n", __FUNCTION__, __LINE__));
+
+ //
+ // Sanity checks
+ //
+ if (Data == NULL) {
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+
+ //
+ // Send CMD for read
+ //
+ Data32 = B_READ_CMD;
+ Status = I2cSendCommand (I2cBaseAddress, &Data32, Start, End);
+ *Data = (UINT8) (Data32 & 0xFF);
+
+Exit:
+ //
+ // Pause a bit
+ //
+ MicroSecondDelay (EEPROM_ROUTINE_DELAY);
+ //
+ // Display error messages
+ //
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - Ending with %r\n", __FUNCTION__, __LINE__, Status));
+ }
+ return Status;
+}
+
+//
+// Desc: Resets the I2C controller into a known good state
+// Input: I2cBaseAddress - MMIO base address for the I2C controller
+// Bus - I2C controller, 0 based
+// Address - 7-bit slave address
+// Speed - Uses the I2C_SPEED enum to set the controller speed
+// Output: EFI_SUCCESS - Write completed successfully
+// EFI_DEVICE_ERROR - I2C controller error
+// EFI_INVALID_PARAMETER - Invalid input parameter
+//
+EFI_STATUS
+I2cReset (
+ IN UINT32 I2cBaseAddress,
+ IN UINT8 Bus,
+ IN UINT16 Address,
+ IN UINT8 Speed
+ )
+{
+ UINT16 I2cMode;
+ UINT32 NumTries;
+ EFI_STATUS Status;
+
+ //
+ // Wait for master activity to stop
+ //
+ NumTries = 10000; // 1 seconds
+ while ((STAT_MST_ACTIVITY == (I2cGetStatus (I2cBaseAddress) & STAT_MST_ACTIVITY))) {
+ MicroSecondDelay (10);
+ NumTries--;
+ if (0 == NumTries) {
+ DEBUG ((DEBUG_ERROR, "%a(#%4d) - Try timeout\n", __FUNCTION__, __LINE__));
+ Status = EFI_DEVICE_ERROR;
+ goto Exit;
+ }
+ }
+ //
+ // Abort controller
+ //
+ MmioWrite32 (I2cBaseAddress + R_IC_ENABLE, I2C_ENABLE_ABORT);
+ MicroSecondDelay (10 * EEPROM_ROUTINE_DELAY);
+ //
+ // Disable I2C controller
+ //
+ Status = I2cDisable (I2cBaseAddress);
+ if (gI2cDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - I2cDisable Status = %r\n", __FUNCTION__, __LINE__, Status));
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
+ MicroSecondDelay (EEPROM_ROUTINE_DELAY);
+ //
+ // Set I2C controller speed
+ //
+ I2cSetBusFrequency (Bus, I2cBaseAddress); // Set I2cMode
+ MicroSecondDelay (EEPROM_ROUTINE_DELAY);
+ switch (Speed) {
+ case Standard_Speed:
+ //100K
+ I2cMode = V_SPEED_STANDARD;
+ break;
+
+ case Fast_Speed:
+ //400K
+ I2cMode = V_SPEED_FAST;
+ break;
+
+ case High_Speed:
+ //3.4M
+ I2cMode = V_SPEED_HIGH;
+ break;
+
+ default:
+ //400K
+ I2cMode = V_SPEED_FAST;
+ }
+ I2cMode |= B_IC_RESTART_EN | B_IC_SLAVE_DISABLE | B_MASTER_MODE;
+ //
+ // Set slave address
+ //
+ MmioWrite32 (I2cBaseAddress + R_IC_INTR_MASK, 0x0);
+ if (Address > MAX_I2C_ADDRESS) {
+ Address = (Address & 0x3FF) | IC_TAR_10BITADDR_MASTER;
+ }
+ MmioWrite32 (I2cBaseAddress + R_IC_TAR, Address);
+ MicroSecondDelay (EEPROM_ROUTINE_DELAY);
+ //
+ // Set RX & TX FIFO full threshold to 1 byte
+ //
+ MmioWrite32 (I2cBaseAddress + R_IC_RX_TL, 0);
+ MmioWrite32 (I2cBaseAddress + R_IC_TX_TL, 0);
+ MicroSecondDelay (EEPROM_ROUTINE_DELAY);
+ //
+ // Set I2C Mode
+ //
+ MmioWrite32 (I2cBaseAddress + R_IC_CON, I2cMode);
+ if (gI2cDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - I2cMode: 0x%04x\r\n", __FUNCTION__, __LINE__, I2cMode));
+ MicroSecondDelay (EEPROM_ROUTINE_DELAY);
+ //
+ // Enable I2C controller
+ //
+ Status = I2cEnable (I2cBaseAddress);
+ if (gI2cDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - I2cEnable Status = %r\n", __FUNCTION__, __LINE__, Status));
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
+ MicroSecondDelay (EEPROM_ROUTINE_DELAY);
+ //
+ // Clear TX abort
+ //
+ I2cClearTxAbort (I2cBaseAddress);
+ MicroSecondDelay (EEPROM_ROUTINE_DELAY);
+ //
+ // Clear interrupts
+ //
+ I2cClearInterrupts (I2cBaseAddress);
+ MicroSecondDelay (EEPROM_ROUTINE_DELAY);
+
+Exit:
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - Ending with %r\n", __FUNCTION__, __LINE__, Status));
+ }
+ return Status;
+}
+
+//
+// Desc: Write a byte to the I2C controller
+// Input: I2cBaseAddress - MMIO base address for the I2C controller
+// Data - Data from the I2C controller
+// Start - Send start bit?
+// End - Send end bit?
+// Output: EFI_SUCCESS - Write completed successfully
+// EFI_DEVICE_ERROR - I2C controller error
+// EFI_INVALID_PARAMETER - Invalid input parameter
+//
+EFI_STATUS
+I2cSendCommand (
+ IN UINT32 I2cBaseAddress,
+ IN UINT32 *Data,
+ IN BOOLEAN Start,
+ IN BOOLEAN End
+ )
+{
+ BOOLEAN CommandSent;
+ UINT32 Count;
+ UINT32 CountOut;
+ UINT32 Data32;
+ BOOLEAN ReadFlag;
+ EFI_STATUS Status;
+ UINT16 TxAbortStatus;
+
+ //
+ // Initialize variables
+ //
+ CommandSent = FALSE;
+ Count = 0;
+ CountOut = 0x00000100;
+ Status = EFI_NOT_READY;
+ if ((*Data & B_READ_CMD) == B_READ_CMD) {
+ ReadFlag = TRUE;
+ } else {
+ ReadFlag = FALSE;
+ }
+
+ //
+ // Send a command byte
+ //
+ while (CountOut-- > 0) {
+ //
+ // Check for NACK
+ //
+ if ((I2cGetRawStatus (I2cBaseAddress) & I2C_INTR_TX_ABRT) != 0) {
+ TxAbortStatus = I2cGetTxAbortStatus (I2cBaseAddress);
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - TX ABRT [%04x]\n", __FUNCTION__, __LINE__, TxAbortStatus));
+ if (gI2cDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - RX FIFO = %04x\n", __FUNCTION__, __LINE__, I2cGetRxFifo (I2cBaseAddress)));
+ if (gI2cDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - TX FIFO = %04x\n", __FUNCTION__, __LINE__, I2cGetTxFifo (I2cBaseAddress)));
+ //
+ // Clear TX Abort
+ //
+ I2cClearTxAbort (I2cBaseAddress);
+ MicroSecondDelay (EEPROM_WRITE_TIMEOUT);
+ //
+ // Clear interrupts
+ //
+ I2cClearInterrupts (I2cBaseAddress);
+ MicroSecondDelay (EEPROM_WRITE_TIMEOUT);
+ //
+ // Set status
+ //
+ if (TxAbortStatus & (I2C_ABRT_7B_ADDR_NOACK | I2C_ABRT_10ADDR1_NOACK | I2C_ABRT_10ADDR2_NOACK)) {
+ DEBUG ((DEBUG_ERROR, "%a(#%4d) - Nobody home!\n", __FUNCTION__, __LINE__));
+ Status = EFI_NO_RESPONSE;
+ } else {
+ Status = EFI_DEVICE_ERROR;
+ }
+ goto Exit;
+ }
+ //
+ // Determine if another byte was received and we were expecting it
+ //
+ if (((I2cGetStatus (I2cBaseAddress) & STAT_RFNE) != 0) && ReadFlag) {
+ *Data = MmioRead32 (I2cBaseAddress + R_IC_DATA_CMD) & 0xFF;
+ if (gI2cDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - MmioRead32, byte 0x%02x was received [%d:%d]\n", __FUNCTION__, __LINE__, *Data, Start, End));
+ MicroSecondDelay (FIFO_WRITE_DELAY);
+ //
+ // Now empty the RX FIFO if stop bit set
+ //
+ while (End && ((I2cGetStatus (I2cBaseAddress) & STAT_RFNE) == STAT_RFNE)) {
+ MmioRead32 (I2cBaseAddress + R_IC_DATA_CMD);
+ MicroSecondDelay (FIFO_WRITE_DELAY);
+ }
+ if (gI2cDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - RX FIFO = %04x\n", __FUNCTION__, __LINE__, I2cGetRxFifo (I2cBaseAddress)));
+ if (gI2cDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - TX FIFO = %04x\n", __FUNCTION__, __LINE__, I2cGetTxFifo (I2cBaseAddress)));
+ Status = EFI_SUCCESS;
+ goto Exit;
+ }
+ //
+ // Wait for room in TX buffer
+ //
+ if ((I2cGetStatus (I2cBaseAddress) & STAT_TFNF) == 0) {
+ MicroSecondDelay (FIFO_WRITE_DELAY);
+ continue;
+ }
+ if (!CommandSent) {
+ //
+ // Send CMD
+ //
+ Data32 = *Data;
+ if (Start) Data32 |= B_CMD_RESTART;
+ if (End) Data32 |= B_CMD_STOP;
+ MmioWrite32 (I2cBaseAddress + R_IC_DATA_CMD, Data32);
+ CommandSent = TRUE;
+ }
+ //
+ // Add a small delay to work around some odd behavior being seen. Without this delay bytes get dropped.
+ //
+ MicroSecondDelay (EEPROM_WRITE_TIMEOUT);
+ //
+ // Time out check for write CMD
+ //
+ while (!ReadFlag) {
+ if ((I2cGetRawStatus (I2cBaseAddress) & I2C_INTR_TX_ABRT) != 0) {
+ TxAbortStatus = I2cGetTxAbortStatus (I2cBaseAddress);
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - TX ABRT [%04x]\n", __FUNCTION__, __LINE__, TxAbortStatus));
+ //
+ // Clear TX Abort
+ //
+ I2cClearTxAbort (I2cBaseAddress);
+ MicroSecondDelay (EEPROM_WRITE_TIMEOUT);
+ //
+ // Clear interrupts
+ //
+ I2cClearInterrupts (I2cBaseAddress);
+ MicroSecondDelay (EEPROM_WRITE_TIMEOUT);
+ //
+ // Set status
+ //
+ if (TxAbortStatus & (I2C_ABRT_7B_ADDR_NOACK | I2C_ABRT_10ADDR1_NOACK | I2C_ABRT_10ADDR2_NOACK)) {
+ DEBUG ((DEBUG_ERROR, "%a(#%4d) - Nobody home!\n", __FUNCTION__, __LINE__));
+ Status = EFI_NO_RESPONSE;
+ } else {
+ Status = EFI_DEVICE_ERROR;
+ }
+ }
+ if (I2cGetTxFifo (I2cBaseAddress) == 0) {
+ if (gI2cDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - MmioRead32, byte 0x%04x was sent [%d:%d]\n", __FUNCTION__, __LINE__, Data32, Start, End));
+ if (gI2cDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - RX FIFO = %04x\n", __FUNCTION__, __LINE__, I2cGetRxFifo (I2cBaseAddress)));
+ if (gI2cDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - TX FIFO = %04x\n", __FUNCTION__, __LINE__, I2cGetTxFifo (I2cBaseAddress)));
+ Status = EFI_SUCCESS;
+ goto Exit;
+ }
+ MicroSecondDelay (EEPROM_WRITE_TIMEOUT);
+ if (Count++ < 1024) { //to avoid sys hung without ul-pmc device on RVP
+ continue; //Waiting the last request to get data and make (ReceiveDataEnd > ReadBuffer) =TRUE.
+ } else {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - hardware timeout, 1024 times try!\n", __FUNCTION__, __LINE__));
+ Status = EFI_TIMEOUT;
+ goto Exit;
+ }
+ }
+ }
+
+ //
+ // Check for count out
+ //
+ if (CountOut == 0) {
+ Status = EFI_TIMEOUT;
+ }
+
+Exit:
+ //
+ // Pause a bit
+ //
+ MicroSecondDelay (EEPROM_ROUTINE_DELAY);
+ //
+ // Display error messages
+ //
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - Ending with %r [%x]\n", __FUNCTION__, __LINE__, Status, CountOut));
+ }
+ return Status;
+}
+
+//
+// Desc: Set I2C target slave offset
+// Input: I2cBaseAddress - MMIO base address for the I2C controller
+// Offset - Pointer to offset data
+// Size - Size of the offset data
+// Output: EFI_SUCCESS - Write completed successfully
+// EFI_DEVICE_ERROR - I2C controller error
+// EFI_INVALID_PARAMETER - Invalid input parameter
+//
+EFI_STATUS
+I2cSetOffset (
+ IN UINT32 I2cBaseAddress,
+ IN UINT8 *Offset,
+ IN UINT8 Size
+ )
+{
+ UINT8 index;
+ EFI_STATUS Status;
+
+ if (gI2cDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Starting\n", __FUNCTION__, __LINE__));
+
+ //
+ // Sanity checks
+ //
+ if (Offset == NULL) {
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ if (Size == 0) {
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ //
+ // Set offset
+ //
+ for (index = 0; index < Size; index++) {
+ if (index == 0) {
+ //
+ // First byte of the offset
+ //
+ Status = I2cWrite (I2cBaseAddress, Offset[index], TRUE, FALSE);
+ } else {
+ Status = I2cWrite (I2cBaseAddress, Offset[index], FALSE, FALSE);
+ }
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
+ //
+ // Pause a bit
+ //
+ MicroSecondDelay (EEPROM_WRITE_TIMEOUT);
+ }
+
+Exit:
+ //
+ // Pause a bit
+ //
+ MicroSecondDelay (EEPROM_ROUTINE_DELAY);
+ //
+ // Display error messages
+ //
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - Ending with %r\n", __FUNCTION__, __LINE__, Status));
+ }
+ return Status;
+}
+
+//
+// Desc: Write a byte to the I2C controller
+// Input: I2cBaseAddress - MMIO base address for the I2C controller
+// Data - Data from the I2C controller
+// Start - Send start bit?
+// End - Send end bit?
+// Output: EFI_SUCCESS - Write completed successfully
+// EFI_DEVICE_ERROR - I2C controller error
+// EFI_INVALID_PARAMETER - Invalid input parameter
+//
+EFI_STATUS
+I2cWrite (
+ IN UINT32 I2cBaseAddress,
+ IN UINT8 Data,
+ IN BOOLEAN Start,
+ IN BOOLEAN End
+ )
+{
+ UINT32 Data32;
+ EFI_STATUS Status;
+
+ if (gI2cDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Starting\n", __FUNCTION__, __LINE__));
+
+ //
+ // Send CMD for write
+ //
+ Data32 = Data;
+ Status = I2cSendCommand (I2cBaseAddress, &Data32, Start, End);
+ //
+ // Pause a bit
+ //
+ MicroSecondDelay (EEPROM_ROUTINE_DELAY);
+ //
+ // Display error messages
+ //
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - Ending with %r\n", __FUNCTION__, __LINE__, Status));
+ }
+ return Status;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/EEPROM/I2cLib.h b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/EEPROM/I2cLib.h
new file mode 100644
index 0000000000..4134caa6a6
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/EEPROM/I2cLib.h
@@ -0,0 +1,181 @@
+/** @file
+ Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
+
+ 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 _EEPROM_I2C_LIB_
+#define _EEPROM_I2C_LIB_
+////
+//// Header files
+////
+#include <Uefi.h>
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/EepromDataLib.h>
+#include <Library/GpioLib.h>
+#include <Library/PcdLib.h>
+#include <Library/TimerLib.h>
+
+#include <PlatformBaseAddresses.h>
+#include <SaAccess.h>
+#include <ScAccess.h>
+#include <ScRegs/RegsI2c.h>
+
+//
+// Defines
+//
+#define EEPROM_WRITE_TIMEOUT 5
+#define FIFO_WRITE_DELAY 5
+#define EEPROM_ROUTINE_DELAY 10
+#define INVALID_I2C_ADDRESS 0xFF
+#define MAX_I2C_ADDRESS 0x7F
+#define MAX_I2C_BUS 7
+
+//
+// Enums
+//
+typedef enum {
+ Standard_Speed = 1,
+ Fast_Speed = 2,
+ High_Speed = 3,
+ Max_Speed = 3
+} I2C_SPEED;
+
+//
+// Externs
+//
+extern BOOLEAN gI2cDebugFlag;
+
+//
+// Structures
+//
+typedef struct _LPSS_PCI_DEVICE_INFO {
+ UINT8 Segment;
+ UINT8 BusNum;
+ UINT8 DeviceNum;
+ UINT8 FunctionNum;
+ UINT32 Bar0;
+ UINT32 Bar1;
+} LPSS_PCI_DEVICE_INFO;
+
+typedef struct _LPSS_I2C_CLOCK_SCL_INFO {
+ UINT16 SS_SCL_HCNT;
+ UINT16 SS_SCL_LCNT;
+ UINT16 FS_SCL_HCNT;
+ UINT16 FS_SCL_LCNT;
+ UINT16 HS_SCL_HCNT;
+ UINT16 HS_SCL_LCNT;
+} LPSS_I2C_CLOCK_SCL_INFO;
+
+//
+// Functions
+//
+//
+// Desc: Initializes the controller and returns the MMIO base address
+// Input: Bus - I2C controller, 0 based
+// Address - 7-bit slave address
+// Speed - Uses the I2C_SPEED enum to set the controller speed
+// I2cBaseAddress - Pointer to the MMIO base address for the I2C controller
+// Output: EFI_SUCCESS - Initialization completed successfully
+// EFI_DEVICE_ERROR - I2C controller error
+// EFI_INVALID_PARAMETER - Invalid input parameter
+//
+EFI_STATUS
+I2cInit (
+ IN UINT8 Bus,
+ IN UINT16 Address,
+ IN UINT8 Speed,
+ IN OUT UINT32 *I2cBaseAddress
+ );
+
+EFI_STATUS
+I2cPoll (
+ IN UINT32 I2cBaseAddress
+ );
+
+//
+// Desc: Read a byte from the I2C controller
+// Input: I2cBaseAddress - MMIO base address for the I2C controller
+// Data - Pointer to where to store the data
+// Start - Send start bit?
+// End - Send end bit?
+// Output: EFI_SUCCESS - Read completed successfully
+// EFI_DEVICE_ERROR - I2C controller error
+// EFI_INVALID_PARAMETER - Invalid input parameter
+//
+EFI_STATUS
+I2cRead (
+ IN UINT32 I2cBaseAddress,
+ IN OUT UINT8 *Data,
+ IN BOOLEAN Start,
+ IN BOOLEAN End
+ );
+
+//
+// Desc: Resets the I2C controller into a known good state
+// Input: I2cBaseAddress - MMIO base address for the I2C controller
+// Output: EFI_SUCCESS - Write completed successfully
+// EFI_DEVICE_ERROR - I2C controller error
+// EFI_INVALID_PARAMETER - Invalid input parameter
+//
+EFI_STATUS
+I2cReset (
+ IN UINT32 I2cBaseAddress,
+ IN UINT8 Bus,
+ IN UINT16 Address,
+ IN UINT8 Speed
+ );
+
+EFI_STATUS
+I2cSendCommand (
+ IN UINT32 I2cBaseAddress,
+ IN UINT32 *Data,
+ IN BOOLEAN Start,
+ IN BOOLEAN End
+ );
+
+//
+// Desc: Set I2C slave offset
+// Input: I2cBaseAddress - MMIO base address for the I2C controller
+// Offset - Pointer to offset data
+// Size - Size of the offset data
+// Output: EFI_SUCCESS - Write completed successfully
+// EFI_DEVICE_ERROR - I2C controller error
+// EFI_INVALID_PARAMETER - Invalid input parameter
+//
+EFI_STATUS
+I2cSetOffset (
+ IN UINT32 I2cBaseAddress,
+ IN UINT8 *Offset,
+ IN UINT8 Size
+ );
+
+//
+// Desc: Write a byte to the I2C controller
+// Input: I2cBaseAddress - MMIO base address for the I2C controller
+// Data - Data from the I2C controller
+// Start - Send start bit?
+// End - Send end bit?
+// Output: EFI_SUCCESS - Write completed successfully
+// EFI_DEVICE_ERROR - I2C controller error
+// EFI_INVALID_PARAMETER - Invalid input parameter
+//
+EFI_STATUS
+I2cWrite (
+ IN UINT32 I2cBaseAddress,
+ IN UINT8 Data,
+ IN BOOLEAN Start,
+ IN BOOLEAN End
+ );
+
+#endif // _EEPROM_I2C_LIB_
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/EepromDataLib.c b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/EepromDataLib.c
new file mode 100644
index 0000000000..e5ffc85491
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/EepromDataLib.c
@@ -0,0 +1,216 @@
+/** @file
+ Common EEPROM raw data library instance.
+
+ Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
+
+ 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 "EepromDataLib.h"
+
+BOOLEAN mEepromDataLibDebugFlag = FALSE;
+EEPROM_DATA_LIBRARY_INDEX mEepromDataLibIndex[EEPROM_DATA_LIBRARY_INDEX_MAX];
+CHAR8 *mEepromLibraryString[EEPROM_DATA_LIBRARY_INDEX_MAX] = {
+ {"EEPROM_NULL"},
+ {"EEPROM_EEPROM"},
+ {"EEPROM_FV"},
+ {"EEPROM_MEMORY"}
+ };
+
+//
+// Desc: Reads from the EEPROM and copies to the passed in buffer.
+// Variables: LibraryIndex Determines which raw data library to use
+// Offset Start copying from the offset
+// Size Size of the buffer and the number of bytes to copy
+// - If set to 0, then return size of EEPROM binary
+// Buffer Storage buffer for the copied data from the EEPROM
+// FunctionInfo Pointer to function specific data
+// Return: EFI_SUCCESS Data copied successfully
+// EFI_UNSUPPORTED This function is not supported
+// EFI_INVALID_PARAMETER One of the parameters is invalid
+// EFI_NOT_READY Called before all necessary library available
+// EFI_DEVICE_ERROR Communication error with device
+//
+EFI_STATUS
+EFIAPI
+ReadEeprom (
+ IN UINT8 LibraryIndex,
+ IN UINT32 Offset,
+ IN OUT UINT32 *Size,
+ IN OUT UINT8 *Buffer,
+ IN OUT VOID *FunctionInfo
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Sanity checks
+ //
+ if (LibraryIndex >= EEPROM_DATA_LIBRARY_INDEX_MAX) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - LibraryIndex out of range\n", __FUNCTION__, __LINE__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ if (Size == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - Size == NULL\n", __FUNCTION__, __LINE__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ if (Buffer == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - Buffer == NULL\n", __FUNCTION__, __LINE__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ if (mEepromDataLibIndex[LibraryIndex].Active == FALSE) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - Library %a is not active\n", __FUNCTION__, __LINE__, mEepromLibraryString[LibraryIndex]));
+ Status = EFI_NOT_READY;
+ goto Exit;
+ }
+
+ //
+ // Call function
+ //
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Calling EEPROM raw library %a read function\n", __FUNCTION__, __LINE__, mEepromLibraryString[LibraryIndex]));
+ Status = mEepromDataLibIndex[LibraryIndex].ReadFunction (Offset, Size, Buffer, FunctionInfo);
+
+Exit:
+ if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) {
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_ERROR, "%a (#%4d) - Ending with %r\n", __FUNCTION__, __LINE__, Status));
+ }
+ return Status;
+}
+
+//
+// Desc: Writes to the EEPROM and copies to the passed in buffer.
+// Variables: LibraryIndex Determines which raw data library to use
+// Offset Start copying from the offset
+// - If set to 0, then return size of EEPROM binary
+// Size Size of the buffer and the number of bytes to copy
+// Buffer Data to be copied to the EEPROM
+// FunctionInfo Pointer to function specific data
+// Return: EFI_SUCCESS Data copied successfully
+// EFI_UNSUPPORTED This function is not supported
+// EFI_INVALID_PARAMETER One of the parameters is invalid
+// EFI_NOT_READY Called before all necessary library available
+// EFI_DEVICE_ERROR Communication error with device
+//
+EFI_STATUS
+EFIAPI
+WriteEeprom (
+ IN UINT8 LibraryIndex,
+ IN UINT32 Offset,
+ IN OUT UINT32 *Size,
+ IN OUT UINT8 *Buffer,
+ IN OUT VOID *FunctionInfo
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Sanity checks
+ //
+ if (LibraryIndex >= EEPROM_DATA_LIBRARY_INDEX_MAX) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - LibraryIndex out of range\n", __FUNCTION__, __LINE__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ if (Size == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - Size == NULL\n", __FUNCTION__, __LINE__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ if (Buffer == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - Buffer == NULL\n", __FUNCTION__, __LINE__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ if (mEepromDataLibIndex[LibraryIndex].Active == FALSE) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - Library %a is not active\n", __FUNCTION__, __LINE__, mEepromLibraryString[LibraryIndex]));
+ Status = EFI_NOT_READY;
+ goto Exit;
+ }
+
+ //
+ // Call function
+ //
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Calling EEPROM raw library %a write function\n", __FUNCTION__, __LINE__, mEepromLibraryString[LibraryIndex]));
+ Status = mEepromDataLibIndex[LibraryIndex].WriteFunction (Offset, Size, Buffer, FunctionInfo);
+
+Exit:
+ if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) {
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_ERROR, "%a (#%4d) - Ending with %r\n", __FUNCTION__, __LINE__, Status));
+ }
+ return Status;
+}
+
+//
+// Desc: Registers the raw data libraries
+// Variables: None
+// Return: EFI_SUCCESS, anything else will cause an ASSERT
+//
+EFI_STATUS
+EFIAPI
+EepromDataNullInitConstructor (VOID)
+{
+ //
+ // 00 - NULL raw library
+ //
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Loading EEPROM NULL raw data library into slot #%02x\n", __FUNCTION__, __LINE__, EEPROM_NULL));
+ mEepromDataLibIndex[EEPROM_NULL].Active = TRUE;
+ mEepromDataLibIndex[EEPROM_NULL].ReadFunction = ReadEepromNull;
+ mEepromDataLibIndex[EEPROM_NULL].WriteFunction = WriteEepromNull;
+
+ return EFI_SUCCESS;
+}
+
+//
+// Desc: Registers the raw data libraries
+// Variables: None
+// Return: EFI_SUCCESS, anything else will cause an ASSERT
+//
+EFI_STATUS
+EFIAPI
+EepromDataInitConstructor (VOID)
+{
+ //
+ // 00 - NULL raw library
+ //
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Loading EEPROM NULL raw data library into slot #%02x\n", __FUNCTION__, __LINE__, EEPROM_NULL));
+ mEepromDataLibIndex[EEPROM_NULL].Active = TRUE;
+ mEepromDataLibIndex[EEPROM_NULL].ReadFunction = ReadEepromNull;
+ mEepromDataLibIndex[EEPROM_NULL].WriteFunction = WriteEepromNull;
+
+ //
+ // 01 - EEPROM raw library
+ //
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Loading EEPROM raw data library into slot #%02x\n", __FUNCTION__, __LINE__, EEPROM_EEPROM));
+ mEepromDataLibIndex[EEPROM_EEPROM].Active = TRUE;
+ mEepromDataLibIndex[EEPROM_EEPROM].ReadFunction = ReadEepromEeprom;
+ mEepromDataLibIndex[EEPROM_EEPROM].WriteFunction = WriteEepromEeprom;
+
+ //
+ // 02 - FV raw library
+ //
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Loading EEPROM FV raw data library into slot #%02x\n", __FUNCTION__, __LINE__, EEPROM_FV));
+ mEepromDataLibIndex[EEPROM_FV].Active = TRUE;
+ mEepromDataLibIndex[EEPROM_FV].ReadFunction = ReadEepromFv;
+ mEepromDataLibIndex[EEPROM_FV].WriteFunction = WriteEepromFv;
+
+ //
+ // 03 - Memory raw library
+ //
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Loading EEPROM memory raw data library into slot #%02x\n", __FUNCTION__, __LINE__, EEPROM_MEMORY));
+ mEepromDataLibIndex[EEPROM_MEMORY].Active = TRUE;
+ mEepromDataLibIndex[EEPROM_MEMORY].ReadFunction = ReadEepromMemory;
+ mEepromDataLibIndex[EEPROM_MEMORY].WriteFunction = WriteEepromMemory;
+
+ return EFI_SUCCESS;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/EepromDataLib.h b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/EepromDataLib.h
new file mode 100644
index 0000000000..899487ab46
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/EepromDataLib.h
@@ -0,0 +1,290 @@
+/** @file
+ Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
+
+ 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 _EEPROM_DATA_LIB_COMMON_
+#define _EEPROM_DATA_LIB_COMMON_
+////
+//// Header files
+////
+#include <Uefi.h>
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/EepromDataLib.h>
+#include <Library/PrintLib.h>
+
+////
+//// Defines
+////
+#define ALLOCATION_HOB_HEADER_SIGNATURE SIGNATURE_32 ('e', 'H', 'B', 'a')
+#define MAX_EEPROM_HOB_SIZE (25 * 1024)
+#define MAX_EEPROM_ALLOCATION_FLAG ((MAX_EEPROM_HOB_SIZE / 0x10) / 8)
+#define MAX_EEPROM_ALLOCATION_SIZE (MAX_EEPROM_HOB_SIZE - MAX_EEPROM_ALLOCATION_FLAG)
+
+////
+//// TypeDefs
+////
+typedef
+EFI_STATUS
+(EFIAPI *NEM_TO_MEMORY_EEPROM_FUNCTION) (VOID);
+
+typedef
+EFI_STATUS
+(EFIAPI *READ_EEPROM_FUNCTION) (
+ IN UINT32 Offset,
+ IN OUT UINT32 *Size,
+ IN OUT UINT8 *Buffer,
+ IN OUT VOID *FunctionInfo
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *WRITE_EEPROM_FUNCTION) (
+ IN UINT32 Offset,
+ IN OUT UINT32 *Size,
+ IN OUT UINT8 *Buffer,
+ IN OUT VOID *FunctionInfo
+ );
+
+////
+//// Structures
+////
+typedef struct {
+ BOOLEAN Active;
+ READ_EEPROM_FUNCTION ReadFunction;
+ WRITE_EEPROM_FUNCTION WriteFunction;
+} EEPROM_DATA_LIBRARY_INDEX;
+
+typedef struct {
+ UINT32 Signature;
+ UINT8 UsageFlag[MAX_EEPROM_ALLOCATION_FLAG]; // Size / paragraph / byte size
+} EEPROM_ALLOCATION_STRUCT;
+
+////
+//// Functions
+////
+//
+// Desc: Copies any data from NEM into real memory
+// Variables: NONE
+// Return: EFI_SUCCESS Data copied successfully
+// EFI_UNSUPPORTED This function is not supported
+// EFI_INVALID_PARAMETER One of the parameters is invalid
+//
+EFI_STATUS
+EFIAPI
+NemToMemoryEepromEeprom (VOID);
+
+//
+// Desc: Reads from the EEPROM and copies to the passed in buffer.
+// Variables: Offset Start copying from the offset
+// Size Size of the buffer and the number of bytes to copy
+// Buffer Storage buffer for the copied data from the EEPROM
+// FunctionInfo Pointer to function specific data
+// Return: EFI_SUCCESS Data copied successfully
+// EFI_UNSUPPORTED This function is not supported
+// EFI_INVALID_PARAMETER One of the parameters is invalid
+// EFI_NOT_READY Called before all necessary protocols available
+// EFI_DEVICE_ERROR Communication error with device
+//
+EFI_STATUS
+EFIAPI
+ReadEepromEeprom (
+ IN UINT32 Offset,
+ IN OUT UINT32 *Size,
+ IN OUT UINT8 *Buffer,
+ IN OUT VOID *FunctionInfo
+ );
+
+//
+// Desc: Writes to the EEPROM and copies to the passed in buffer.
+// Variables: Offset Start copying from the offset
+// Size Size of the buffer and the number of bytes to copy
+// Buffer Storage buffer for the copied data to the EEPROM
+// FunctionInfo Pointer to function specific data
+// Return: EFI_SUCCESS Data copied successfully
+// EFI_UNSUPPORTED This function is not supported
+// EFI_INVALID_PARAMETER One of the parameters is invalid
+// EFI_NOT_READY Called before all necessary protocols available
+// EFI_DEVICE_ERROR Communication error with device
+//
+EFI_STATUS
+EFIAPI
+WriteEepromEeprom (
+ IN UINT32 Offset,
+ IN OUT UINT32 *Size,
+ IN OUT UINT8 *Buffer,
+ IN OUT VOID *FunctionInfo
+ );
+
+//
+// Desc: Copies any data from NEM into real memory
+// Variables: NONE
+// Return: EFI_SUCCESS Data copied successfully
+// EFI_UNSUPPORTED This function is not supported
+// EFI_INVALID_PARAMETER One of the parameters is invalid
+//
+EFI_STATUS
+EFIAPI
+NemToMemoryEepromFv (VOID);
+
+//
+// Desc: Reads from the EEPROM and copies to the passed in buffer.
+// Variables: Offset Start copying from the offset
+// Size Size of the buffer and the number of bytes to copy
+// Buffer Storage buffer for the copied data from the EEPROM
+// FunctionInfo Pointer to function specific data
+// Return: EFI_SUCCESS Data copied successfully
+// EFI_UNSUPPORTED This function is not supported
+// EFI_INVALID_PARAMETER One of the parameters is invalid
+// EFI_NOT_READY Called before all necessary protocols available
+// EFI_DEVICE_ERROR Communication error with device
+//
+EFI_STATUS
+EFIAPI
+ReadEepromFv (
+ IN UINT32 Offset,
+ IN OUT UINT32 *Size,
+ IN OUT UINT8 *Buffer,
+ IN OUT VOID *FunctionInfo
+ );
+
+//
+// Desc: Writes to the EEPROM and copies to the passed in buffer.
+// Variables: Offset Start copying from the offset
+// Size Size of the buffer and the number of bytes to copy
+// Buffer Storage buffer for the copied data to the EEPROM
+// FunctionInfo Pointer to function specific data
+// Return: EFI_SUCCESS Data copied successfully
+// EFI_UNSUPPORTED This function is not supported
+// EFI_INVALID_PARAMETER One of the parameters is invalid
+// EFI_NOT_READY Called before all necessary protocols available
+// EFI_DEVICE_ERROR Communication error with device
+//
+EFI_STATUS
+EFIAPI
+WriteEepromFv (
+ IN UINT32 Offset,
+ IN OUT UINT32 *Size,
+ IN OUT UINT8 *Buffer,
+ IN OUT VOID *FunctionInfo
+ );
+
+//
+// Desc: Copies any data from NEM into real memory
+// Variables: NONE
+// Return: EFI_SUCCESS Data copied successfully
+// EFI_UNSUPPORTED This function is not supported
+// EFI_INVALID_PARAMETER One of the parameters is invalid
+//
+EFI_STATUS
+EFIAPI
+NemToMemoryEepromMemory (VOID);
+
+//
+// Desc: Reads from the EEPROM and copies to the passed in buffer.
+// Variables: Offset Start copying from the offset
+// Size Size of the buffer and the number of bytes to copy
+// Buffer Storage buffer for the copied data from the EEPROM
+// FunctionInfo Pointer to function specific data
+// Return: EFI_SUCCESS Data copied successfully
+// EFI_UNSUPPORTED This function is not supported
+// EFI_INVALID_PARAMETER One of the parameters is invalid
+// EFI_NOT_READY Called before all necessary protocols available
+// EFI_DEVICE_ERROR Communication error with device
+//
+EFI_STATUS
+EFIAPI
+ReadEepromMemory (
+ IN UINT32 Offset,
+ IN OUT UINT32 *Size,
+ IN OUT UINT8 *Buffer,
+ IN OUT VOID *FunctionInfo
+ );
+
+//
+// Desc: Writes to the EEPROM and copies to the passed in buffer.
+// Variables: Offset Start copying from the offset
+// Size Size of the buffer and the number of bytes to copy
+// Buffer Storage buffer for the copied data to the EEPROM
+// FunctionInfo Pointer to function specific data
+// Return: EFI_SUCCESS Data copied successfully
+// EFI_UNSUPPORTED This function is not supported
+// EFI_INVALID_PARAMETER One of the parameters is invalid
+// EFI_NOT_READY Called before all necessary protocols available
+// EFI_DEVICE_ERROR Communication error with device
+//
+EFI_STATUS
+EFIAPI
+WriteEepromMemory (
+ IN UINT32 Offset,
+ IN OUT UINT32 *Size,
+ IN OUT UINT8 *Buffer,
+ IN OUT VOID *FunctionInfo
+ );
+
+//
+// Desc: Copies any data from NEM into real memory
+// Variables: NONE
+// Return: EFI_SUCCESS Data copied successfully
+// EFI_UNSUPPORTED This function is not supported
+// EFI_INVALID_PARAMETER One of the parameters is invalid
+//
+EFI_STATUS
+EFIAPI
+NemToMemoryEepromNull (VOID);
+
+//
+// Desc: Reads from the EEPROM and copies to the passed in buffer.
+// Variables: Offset Start copying from the offset
+// Size Size of the buffer and the number of bytes to copy
+// Buffer Storage buffer for the copied data from the EEPROM
+// FunctionInfo Pointer to function specific data
+// Return: EFI_SUCCESS Data copied successfully
+// EFI_UNSUPPORTED This function is not supported
+// EFI_INVALID_PARAMETER One of the parameters is invalid
+// EFI_NOT_READY Called before all necessary protocols available
+// EFI_DEVICE_ERROR Communication error with device
+//
+EFI_STATUS
+EFIAPI
+ReadEepromNull (
+ IN UINT32 Offset,
+ IN OUT UINT32 *Size,
+ IN OUT UINT8 *Buffer,
+ IN OUT VOID *FunctionInfo
+ );
+
+//
+// Desc: Writes to the EEPROM and copies to the passed in buffer.
+// Variables: Offset Start copying from the offset
+// Size Size of the buffer and the number of bytes to copy
+// Buffer Storage buffer for the copied data to the EEPROM
+// FunctionInfo Pointer to function specific data
+// Return: EFI_SUCCESS Data copied successfully
+// EFI_UNSUPPORTED This function is not supported
+// EFI_INVALID_PARAMETER One of the parameters is invalid
+// EFI_NOT_READY Called before all necessary protocols available
+// EFI_DEVICE_ERROR Communication error with device
+//
+EFI_STATUS
+EFIAPI
+WriteEepromNull (
+ IN UINT32 Offset,
+ IN OUT UINT32 *Size,
+ IN OUT UINT8 *Buffer,
+ IN OUT VOID *FunctionInfo
+ );
+
+#endif // _EEPROM_DATA_LIB_COMMON_
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/EepromDataLib.inf b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/EepromDataLib.inf
new file mode 100644
index 0000000000..67416aef46
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/EepromDataLib.inf
@@ -0,0 +1,80 @@
+## @file
+# Library producing EEPROM raw data functionality.
+#
+# Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+# 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 = 0x00010017
+ BASE_NAME = EepromDataLib
+ FILE_GUID = D3055446-DA60-4A6D-8D9C-D44CC2C42CA0
+ VERSION_STRING = 1.0
+ MODULE_TYPE = BASE
+ LIBRARY_CLASS = EepromDataLib
+ CONSTRUCTOR = EepromDataInitConstructor
+
+[Depex]
+ TRUE
+
+[Guids]
+ gEepromVariableGuid
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ GpioLib
+ HobLib
+ MemoryAllocationLib
+ PcdLib
+ PrintLib
+ UefiBootServicesTableLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ BroxtonPlatformPkg/PlatformPkg.dec
+ BroxtonSiPkg/BroxtonSiPkg.dec
+
+[Pcd]
+ gPlatformModuleTokenSpaceGuid.PcdEepromFvImageFile
+ gPlatformModuleTokenSpaceGuid.PcdEepromMapHobValid
+ gPlatformModuleTokenSpaceGuid.PcdEepromMemoryHobPresent
+ gPlatformModuleTokenSpaceGuid.PcdEepromMemoryPointer
+ gPlatformModuleTokenSpaceGuid.PcdEepromMemorySize
+ gPlatformModuleTokenSpaceGuid.PcdEepromParts
+ gPlatformModuleTokenSpaceGuid.PcdEepromPartsHeadLink
+ gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress ## SOMETIMES_CONSUMES
+ gEfiBxtTokenSpaceGuid.PcdPmcGcrBaseAddress ## SOMETIMES_CONSUMES
+
+[Protocols]
+ gEfiLoadedImageProtocolGuid
+ gEfiFirmwareVolume2ProtocolGuid
+
+[Sources]
+ EepromDataLib.c
+ EepromDataLib.h
+ MemoryAllocation.c
+ EEPROM/EepromDataEepromLib.c
+ EEPROM/EepromDataEepromLib.h
+ EEPROM/HobData.c
+ EEPROM/I2cLib.c
+ EEPROM/I2cLib.h
+ FV/EepromDataFvLib.c
+ FV/EepromDataFvLib.h
+ FV/GetImage.c
+ Memory/EepromDataMemoryLib.c
+ Memory/EepromDataMemoryLib.h
+ Memory/HobData.c
+ Null/EepromDataNullLib.c
+ Null/EepromDataNullLib.h
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/EepromDataNullLib.inf b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/EepromDataNullLib.inf
new file mode 100644
index 0000000000..71cec046d6
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/EepromDataNullLib.inf
@@ -0,0 +1,40 @@
+## @file
+# Library producing EEPROM raw data functionality.
+#
+# Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+# 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 = 0x00010017
+ BASE_NAME = EepromDataNullLib
+ FILE_GUID = 5FFC9D08-59AD-41EE-B237-6BDE9B900A73
+ VERSION_STRING = 1.0
+ MODULE_TYPE = BASE
+ LIBRARY_CLASS = EepromDataNullLib
+ CONSTRUCTOR = EepromDataNullInitConstructor
+
+[Depex]
+ TRUE
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+
+[Sources]
+ EepromDataLib.c
+ EepromDataLib.h
+ Null/EepromDataNullLib.c
+ Null/EepromDataNullLib.h
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/EepromDataPeiLib.inf b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/EepromDataPeiLib.inf
new file mode 100644
index 0000000000..86a047e4df
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/EepromDataPeiLib.inf
@@ -0,0 +1,75 @@
+## @file
+# Library producing EEPROM raw data functionality.
+#
+# Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+# 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 = 0x00010017
+ BASE_NAME = EepromDataPeiLib
+ FILE_GUID = 6341E204-DEC0-402B-BD12-40D221ED5E54
+ VERSION_STRING = 1.0
+ MODULE_TYPE = BASE
+ LIBRARY_CLASS = EepromDataPeiLib
+ CONSTRUCTOR = EepromDataInitConstructor
+
+[Depex]
+ TRUE
+
+[Guids]
+ gEepromVariableGuid
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ GpioLib
+ HobLib
+ PcdLib
+ PeiServicesLib
+ PrintLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ BroxtonPlatformPkg/PlatformPkg.dec
+ BroxtonSiPkg/BroxtonSiPkg.dec
+
+[Pcd]
+ gPlatformModuleTokenSpaceGuid.PcdEepromFvImageFile
+ gPlatformModuleTokenSpaceGuid.PcdEepromMapHobValid
+ gPlatformModuleTokenSpaceGuid.PcdEepromMemoryHobPresent
+ gPlatformModuleTokenSpaceGuid.PcdEepromMemoryPointer
+ gPlatformModuleTokenSpaceGuid.PcdEepromMemorySize
+ gPlatformModuleTokenSpaceGuid.PcdEepromParts
+ gPlatformModuleTokenSpaceGuid.PcdEepromPartsHeadLink
+ gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress ## SOMETIMES_CONSUMES
+ gEfiBxtTokenSpaceGuid.PcdPmcGcrBaseAddress ## SOMETIMES_CONSUMES
+
+[Sources]
+ EepromDataLib.c
+ EepromDataLib.h
+ MemoryAllocationPei.c
+ EEPROM/EepromDataEepromLib.c
+ EEPROM/EepromDataEepromLib.h
+ EEPROM/HobDataPei.c
+ EEPROM/I2cLib.c
+ EEPROM/I2cLib.h
+ FV/EepromDataFvLib.c
+ FV/EepromDataFvLib.h
+ FV/GetImagePei.c
+ Memory/EepromDataMemoryLib.c
+ Memory/EepromDataMemoryLib.h
+ Memory/HobDataPei.c
+ Null/EepromDataNullLib.c
+ Null/EepromDataNullLib.h
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/FV/EepromDataFvLib.c b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/FV/EepromDataFvLib.c
new file mode 100644
index 0000000000..c503a83720
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/FV/EepromDataFvLib.c
@@ -0,0 +1,172 @@
+/** @file
+ FV EEPROM raw data library instance.
+
+ Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
+
+ 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 "EepromDataFvLib.h"
+
+//
+// Desc: Reads from the EEPROM and copies to the passed in buffer.
+// Variables: Offset Start copying from the offset
+// Size Size of the buffer and the number of bytes to copy
+// - If set to 0, then return size of EEPROM binary
+// Buffer Storage buffer for the copied data from the EEPROM
+// FunctionInfo Pointer to function specific data
+// Return: EFI_SUCCESS Data copied successfully
+// EFI_UNSUPPORTED This function is not supported
+// EFI_INVALID_PARAMETER One of the parameters is invalid
+// EFI_NOT_READY Called before all necessary protocols available
+// EFI_DEVICE_ERROR Communication error with device
+//
+EFI_STATUS
+EFIAPI
+ReadEepromFv (
+ IN UINT32 Offset,
+ IN OUT UINT32 *Size,
+ IN OUT UINT8 *Buffer,
+ IN OUT VOID *FunctionInfo
+ )
+{
+ VOID *Address;
+ FV_FUNCTION_INFO *FvInfo;
+ EFI_GUID FvSectionGuid;
+ UINTN FvSize;
+ VOID *Ptr;
+ EFI_STATUS Status;
+
+ //
+ // Initialize variables
+ //
+ CopyMem (&FvSectionGuid, PcdGetPtr (PcdEepromFvImageFile), sizeof (EFI_GUID));
+ Address = NULL;
+ FvInfo = (FV_FUNCTION_INFO *) FunctionInfo;
+ FvSize = 0;
+
+ //
+ // Sanity checks
+ //
+ // NOTE: Input parameters already checked in wrapper function.
+ //
+ if (FvInfo != NULL) {
+ if ((FvInfo->LibraryIndex == EEPROM_FV) & (FvInfo->FvFileGuid != NULL)) {
+ //
+ // Looking for a different FV file than the EEPROM image
+ //
+ CopyMem (&FvSectionGuid, FvInfo->FvFileGuid, sizeof (EFI_GUID));
+ }
+ }
+
+ //
+ // Grab file from FV
+ //
+ Status = GetImage (
+ &FvSectionGuid,
+ &Address,
+ &FvSize
+ );
+
+ if (!EFI_ERROR (Status)) {
+ //
+ // EEPROM image is present in FV
+ //
+ if (Address != NULL) {
+ Ptr = Address;
+ DEBUG ((DEBUG_INFO, "%a (#%4d) - Found EEPROM image @ 0x%08x.\n", __FUNCTION__, __LINE__, Address));
+ if (*Size == 0) {
+ //
+ // Nothing to copy, return FV EEPROM size.
+ //
+ *Size = (UINT32) FvSize;
+ Status = EFI_BUFFER_TOO_SMALL;
+ DEBUG ((DEBUG_INFO, "%a (#%4d) - EEPROM size = 0x%08x\n", __FUNCTION__, __LINE__, *Size));
+ } else {
+ //
+ // Figure out the correct buffer size.
+ //
+ if ((*Size + Offset) > FvSize) {
+ //
+ // Buffer is larger than what is left in the FV. Update the passed in size.
+ //
+ if (FvSize < Offset) {
+ //
+ // Offset is larger than the FV size. Return 0.
+ //
+ *Size = 0;
+ } else {
+ if (((UINT32) FvSize - Offset) > *Size) {
+ //
+ // Buffer isn't large enough. Bail.
+ //
+ *Size = (UINT32) FvSize - Offset;
+ Status = EFI_BUFFER_TOO_SMALL;
+ goto Exit;
+ } else {
+ *Size = (UINT32) FvSize - Offset;
+ }
+ }
+ }
+ DEBUG ((DEBUG_INFO, "%a (#%4d) - Copying 0x%08x bytes of data starting at offset 0x%08x...\n", __FUNCTION__, __LINE__, *Size, Offset));
+ if (*Size > 0) {
+ //
+ // Asking to copy something
+ //
+ Address = (VOID *) ((UINT8 *) Address + Offset);
+ CopyMem ((VOID *) Buffer, Address, *Size);
+ }
+ }
+ //
+ // GetImage () allocated buffer for Address, now clear it
+ //
+ FreePool (Ptr);
+ Ptr = NULL;
+ }
+ }
+
+Exit:
+ if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - Ending with %r\n", __FUNCTION__, __LINE__, Status));
+ }
+ return Status;
+}
+
+//
+// Desc: Writes to the EEPROM and copies to the passed in buffer.
+// Variables: Offset Start copying from the offset
+// Size Size of the buffer and the number of bytes to copy
+// - If set to 0, then return size of EEPROM binary
+// Buffer Data to be copied to the EEPROM
+// FunctionInfo Pointer to function specific data
+// Return: EFI_SUCCESS Data copied successfully
+// EFI_UNSUPPORTED This function is not supported
+// EFI_INVALID_PARAMETER One of the parameters is invalid
+// EFI_NOT_READY Called before all necessary protocols available
+// EFI_DEVICE_ERROR Communication error with device
+//
+EFI_STATUS
+EFIAPI
+WriteEepromFv (
+ IN UINT32 Offset,
+ IN OUT UINT32 *Size,
+ IN OUT UINT8 *Buffer,
+ IN OUT VOID *FunctionInfo
+ )
+{
+ //
+ // Sanity checks
+ //
+ // NOTE: Input parameters already checked in wrapper function.
+ //
+
+ return EFI_UNSUPPORTED;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/FV/EepromDataFvLib.h b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/FV/EepromDataFvLib.h
new file mode 100644
index 0000000000..10544e27d5
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/FV/EepromDataFvLib.h
@@ -0,0 +1,32 @@
+/** @file
+ Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
+
+ 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 _EEPROM_DATA_FV_LIB_
+#define _EEPROM_DATA_FV_LIB_
+
+#include <Uefi.h>
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/EepromDataLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+EFI_STATUS
+EFIAPI
+GetImage (
+ IN EFI_GUID *NameGuid,
+ OUT VOID **Buffer,
+ OUT UINTN *Size
+ );
+
+#endif // _EEPROM_DATA_FV_LIB_
diff --git a/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/FV/GetImage.c b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/FV/GetImage.c
new file mode 100644
index 0000000000..434d9d9496
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/FV/GetImage.c
@@ -0,0 +1,114 @@
+/** @file
+ FV EEPROM raw data library instance.
+
+ Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
+
+ 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 "EepromDataFvLib.h"
+
+#include <PiDxe.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/FirmwareVolume2.h>
+#include <Protocol/LoadedImage.h>
+
+EFI_STATUS
+EFIAPI
+GetImage (
+ IN EFI_GUID *NameGuid,
+ OUT VOID **Buffer,
+ OUT UINTN *Size
+ )
+{
+ UINT32 AuthenticationStatus;
+ EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
+ EFI_HANDLE *HandleBuffer;
+ UINTN HandleCount;
+ EFI_FIRMWARE_VOLUME2_PROTOCOL *ImageFv;
+ UINTN Index;
+ EFI_STATUS Status;
+
+ Status = EFI_NOT_FOUND;
+ ImageFv = NULL;
+
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiFirmwareVolume2ProtocolGuid,
+ NULL,
+ &HandleCount,
+ &HandleBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ //
+ // Couldn't find the FV2 protocol. Bail.
+ //
+ goto Exit;
+ }
+
+ //
+ // Find desired image in all FVs
+ //
+ for (Index = 0; Index < HandleCount; ++Index) {
+ Status = gBS->HandleProtocol (
+ HandleBuffer[Index],
+ &gEfiFirmwareVolume2ProtocolGuid,
+ (VOID **) &Fv
+ );
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
+ if ((ImageFv != NULL) && (Fv == ImageFv)) {
+ continue;
+ }
+
+ //
+ // Found an FV, try to find file.
+ //
+ *Buffer = NULL;
+ *Size = 0;
+ Status = Fv->ReadSection (
+ Fv,
+ NameGuid,
+ EFI_SECTION_RAW,
+ 0,
+ Buffer,
+ Size,
+ &AuthenticationStatus
+ );
+ if (!EFI_ERROR (Status)) {
+ //
+ // Found the file. Bail.
+ //
+ break;
+ }
+ }
+
+ //
+ // Did we find the file?
+ //
+ if (Index == HandleCount) {
+ //
+ // Nope. Clear buffer and size, then bail.
+ //
+ *Buffer = NULL;
+ *Size = 0;
+ Status = EFI_NOT_FOUND;
+ } else {
+ Status = EFI_SUCCESS;
+ }
+
+Exit:
+ if (HandleBuffer != NULL) {
+ FreePool (HandleBuffer);
+ HandleBuffer = NULL;
+ }
+ return Status;
+}
diff --git a/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/FV/GetImagePei.c b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/FV/GetImagePei.c
new file mode 100644
index 0000000000..8e8b4e23ab
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/FV/GetImagePei.c
@@ -0,0 +1,113 @@
+/** @file
+ FV EEPROM raw data PEI library instance.
+
+ Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
+
+ 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 "EepromDataFvLib.h"
+
+#include <PiPei.h>
+#include <Library/PeiServicesLib.h>
+
+EFI_STATUS
+EFIAPI
+GetImage (
+ IN EFI_GUID *NameGuid,
+ OUT VOID **Buffer,
+ OUT UINTN *Size
+ )
+{
+ BOOLEAN FileFound;
+ EFI_PEI_FILE_HANDLE FileHandle;
+ EFI_FV_FILE_INFO FileInfo;
+ UINTN Instance;
+ EFI_COMMON_SECTION_HEADER *Section;
+ EFI_STATUS Status;
+ EFI_PEI_FV_HANDLE VolumeHandle;
+
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Starting...\n", __FUNCTION__, __LINE__));
+
+ //
+ // Initialize variables
+ //
+ FileFound = FALSE;
+ Instance = 0;
+
+ //
+ // Search FVs for the file
+ //
+ while (TRUE) {
+ //
+ // Search thru the FVs
+ //
+ Status = PeiServicesFfsFindNextVolume (Instance++, &VolumeHandle);
+ if (EFI_ERROR (Status)) {
+ //
+ // Error or end of FVs.
+ //
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_ERROR, "%a (#%4d) - PeiServicesFfsFindNextVolume() -> %r\n", __FUNCTION__, __LINE__, Status));
+ goto Exit;
+ }
+ //
+ // Search the FV for the file.
+ //
+ Status = PeiServicesFfsFindFileByName (NameGuid, VolumeHandle, &FileHandle);
+ if (EFI_ERROR (Status)) {
+ //
+ // File not found. Continue search.
+ //
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_ERROR, "%a (#%4d) - PeiServicesFfsFindFileByName() -> %r\n", __FUNCTION__, __LINE__, Status));
+ continue;
+ }
+ //
+ // Search the file for the section.
+ //
+ Status = PeiServicesFfsFindSectionData (EFI_SECTION_RAW, FileHandle, Buffer);
+ if (EFI_ERROR (Status)) {
+ //
+ // Section not found. Continue search.
+ //
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_ERROR, "%a (#%4d) - PeiServicesFfsFindSectionData() -> %r\n", __FUNCTION__, __LINE__, Status));
+ continue;
+ }
+ //
+ // We've got the file and section.
+ //
+ Status = PeiServicesFfsGetFileInfo (FileHandle, &FileInfo);
+ if (EFI_ERROR (Status)) {
+ //
+ // File info error. Continue search.
+ //
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_ERROR, "%a (#%4d) - PeiServicesFfsGetFileInfo() -> %r\n", __FUNCTION__, __LINE__, Status));
+ continue;
+ }
+ FileFound = TRUE;
+ Section = (EFI_COMMON_SECTION_HEADER *) FileInfo.Buffer;
+ if (IS_SECTION2 (Section)) {
+ ASSERT (SECTION2_SIZE (Section) > 0x00FFFFFF);
+ *Size = SECTION2_SIZE (Section) - sizeof (EFI_COMMON_SECTION_HEADER2);
+ } else {
+ *Size = SECTION_SIZE (Section) - sizeof (EFI_COMMON_SECTION_HEADER);
+ }
+ break;
+ }
+
+ if (FileFound) {
+ Status = EFI_SUCCESS;
+ } else {
+ *Buffer = NULL;
+ *Size = 0;
+ }
+
+Exit:
+ return Status;
+}
diff --git a/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/Memory/EepromDataMemoryLib.c b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/Memory/EepromDataMemoryLib.c
new file mode 100644
index 0000000000..2ea1d8b4bf
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/Memory/EepromDataMemoryLib.c
@@ -0,0 +1,242 @@
+/** @file
+ Memory EEPROM raw data library instance.
+
+ Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
+
+ 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 "EepromDataMemoryLib.h"
+
+//
+// Desc: Reads from the EEPROM copy in memory and copies to the passed in buffer.
+// Variables: Offset Start copying from the offset
+// Size Size of the buffer and the number of bytes to copy
+// Buffer Storage buffer for the copied data from the EEPROM
+// FunctionInfo Pointer to function specific data
+// Return: EFI_SUCCESS Data copied successfully
+// EFI_BUFFER_TOO_SMALL Passed in buffer is too small to hold the data
+// requested
+//
+EFI_STATUS
+EFIAPI
+ReadEepromMemory (
+ IN UINT32 Offset,
+ IN OUT UINT32 *Size,
+ IN OUT UINT8 *Buffer,
+ IN OUT VOID *FunctionInfo
+ )
+{
+ UINT8 *Address;
+ UINT8 *EepromMemoryPtr;
+ UINT32 EepromMemorySize;
+ EFI_STATUS Status;
+
+ //
+ // Try to load data from HOB
+ //
+ GetEepromDataHobData ();
+
+ //
+ // Initialize variables
+ //
+ Address = NULL;
+ EepromMemoryPtr = (UINT8 *) (UINTN) PcdGet64 (PcdEepromMemoryPointer);
+ EepromMemorySize = PcdGet32 (PcdEepromMemorySize);
+ Status = EFI_SUCCESS;
+
+ //
+ // Sanity checks
+ //
+ // NOTE: Input parameters already checked in wrapper function.
+ //
+
+ if ((EepromMemoryPtr == NULL) || (EepromMemorySize == 0)) {
+ //
+ // Memory pointer not loaded yet.
+ //
+ Status = EFI_SUCCESS;
+ *Size = 0;
+ goto Exit;
+ }
+
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - EepromMemoryPtr = 0x%08x\n", __FUNCTION__, __LINE__, PcdGet64 (PcdEepromMemoryPointer)));
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - EepromMemorySize = 0x%08x\n", __FUNCTION__, __LINE__, PcdGet32 (PcdEepromMemorySize)));
+ Address = EepromMemoryPtr;
+ if (*Size == 0) {
+ //
+ // Nothing to copy, return EEPROM size.
+ //
+ *Size = EepromMemorySize;
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - EEPROM size = 0x%08x\n", __FUNCTION__, __LINE__, *Size));
+ Status = EFI_BUFFER_TOO_SMALL;
+ goto Exit;
+ } else {
+ //
+ // Figure out the correct buffer size.
+ //
+ if ((*Size + Offset) > EepromMemorySize) {
+ //
+ // Buffer is larger than what is left in the FV. Update the passed in size.
+ //
+ if (EepromMemorySize < Offset) {
+ //
+ // Offset is larger than the FV size. Return 0.
+ //
+ *Size = 0;
+ } else {
+ if ((EepromMemorySize - Offset) > *Size) {
+ //
+ // Buffer isn't large enough. Bail.
+ //
+ *Size = EepromMemorySize - Offset;
+ Status = EFI_BUFFER_TOO_SMALL;
+ goto Exit;
+ } else {
+ *Size = EepromMemorySize - Offset;
+ }
+ }
+ }
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Copying 0x%08x bytes of data...\n", __FUNCTION__, __LINE__, *Size));
+ if (*Size > 0) {
+ //
+ // Asking to copy something
+ //
+ Address = Address + Offset;
+ CopyMem ((VOID *) Buffer, (VOID *) Address, *Size);
+ }
+ }
+
+Exit:
+ if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - Ending with %r\n", __FUNCTION__, __LINE__, Status));
+ }
+ return Status;
+}
+
+//
+// Desc: Writes to the EEPROM memory copy and copies to the passed in buffer.
+// Variables: Offset Start copying from the offset
+// Size Size of the buffer and the number of bytes to copy
+// Buffer Data to be copied to the EEPROM
+// FunctionInfo Pointer to function specific data
+// Return: EFI_SUCCESS Data copied successfully
+// EFI_BUFFER_TOO_SMALL Passed in buffer is too small to hold the data
+// requested
+// EFI_OUT_OF_RESOURCES Unable to allocate memory
+//
+EFI_STATUS
+EFIAPI
+WriteEepromMemory (
+ IN UINT32 Offset,
+ IN OUT UINT32 *Size,
+ IN OUT UINT8 *Buffer,
+ IN OUT VOID *FunctionInfo
+ )
+{
+ UINT8 *EepromMemoryPtr;
+ UINT32 EepromMemorySize;
+ EFI_STATUS Status;
+ UINT8 *TempBuffer;
+ UINT32 TempSize;
+
+ //
+ // Initialize variables
+ //
+ EepromMemoryPtr = (UINT8 *) (UINTN) PcdGet64 (PcdEepromMemoryPointer);
+ EepromMemorySize = PcdGet32 (PcdEepromMemorySize);
+ Status = EFI_SUCCESS;
+ TempBuffer = NULL;
+ TempSize = 0;
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - EepromMemoryPtr = 0x%08x\n", __FUNCTION__, __LINE__, EepromMemoryPtr));
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - EepromMemorySize = 0x%08x\n", __FUNCTION__, __LINE__, EepromMemorySize));
+
+ //
+ // Sanity checks
+ //
+ // NOTE: Input parameters already checked in wrapper function.
+ //
+
+ if (*Size == 0) {
+ //
+ // Return current EEPROM size.
+ //
+ *Size = EepromMemorySize;
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - EEPROM size = 0x%08x\n", __FUNCTION__, __LINE__, *Size));
+ Status = EFI_BUFFER_TOO_SMALL;
+ goto Exit;
+ } else {
+ //
+ // Asking to write data into memory EEPROM buffer.
+ //
+ if ((Offset + *Size) > EepromMemorySize) {
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Incoming buffer is larger than existing buffer.\n", __FUNCTION__, __LINE__));
+ //
+ // Current memory buffer isn't large enough. Save current buffer/size off.
+ //
+ TempBuffer = EepromMemoryPtr;
+ TempSize = EepromMemorySize;
+ //
+ // Clear memory buffer/size.
+ //
+ EepromMemoryPtr = NULL;
+ EepromMemorySize = 0;
+ }
+ if (EepromMemorySize == 0) {
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Memory buffer is NULL, allocating pool.\n", __FUNCTION__, __LINE__));
+ //
+ // Need to allocate buffer.
+ //
+ EepromMemoryPtr = EepromAllocatePool (*Size + Offset);
+ if (EepromMemoryPtr == NULL) {
+ //
+ // Failed to allocate space.
+ //
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+ EepromMemorySize = *Size + Offset;
+ }
+ //
+ // If there is a temp buffer, copy that content over first.
+ //
+ if ((TempBuffer != NULL) && (TempSize > 0)) {
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Copying temp buffer to memory buffer.\n", __FUNCTION__, __LINE__));
+ CopyMem ((VOID *) EepromMemoryPtr, (VOID *) TempBuffer, TempSize);
+ TempBuffer = EepromFreePool (TempBuffer);
+ }
+ //
+ // Copy input buffer to memory buffer.
+ //
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Found EEPROM image @ %08x.\n", __FUNCTION__, __LINE__, EepromMemoryPtr));
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Copying 0x%08x bytes of data, starting at offset 0x%08x...\n", __FUNCTION__, __LINE__, *Size, Offset));
+ CopyMem ((VOID *) (EepromMemoryPtr + Offset), (VOID *) Buffer, *Size);
+ }
+
+Exit:
+ if (Status == EFI_SUCCESS) {
+ //
+ // Save off buffer info
+ //
+ PcdSet64 (PcdEepromMemoryPointer, (UINTN) EepromMemoryPtr);
+ PcdSet32 (PcdEepromMemorySize, EepromMemorySize);
+
+ //
+ // Update HOB
+ //
+ SetEepromDataHobData ();
+ }
+
+ if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - Ending with %r\n", __FUNCTION__, __LINE__, Status));
+ }
+ return Status;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/Memory/EepromDataMemoryLib.h b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/Memory/EepromDataMemoryLib.h
new file mode 100644
index 0000000000..839515d764
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/Memory/EepromDataMemoryLib.h
@@ -0,0 +1,58 @@
+/** @file
+ Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
+
+ 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 _EEPROM_DATA_MEMORY_LIB_
+#define _EEPROM_DATA_MEMORY_LIB_
+////
+//// Header files
+////
+#include <Uefi.h>
+
+#include <Guid/EepromVariable.h>
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/EepromDataLib.h>
+#include <Library/PcdLib.h>
+
+////
+//// Defines
+////
+#define MEMORY_HOB_HEADER_SIGNATURE SIGNATURE_32 ('e', 'H', 'B', 'm')
+#define MEMORY_HOB_HEADER_VERSION 0x00000001
+#define MEMORY_HOB_MAX_DATA_SIZE (30 * 1024)
+
+////
+//// Structures
+////
+typedef struct {
+ UINT32 Signature;
+ UINT32 Version;
+ UINT16 BlockNumber;
+ UINT16 BlockSize;
+ UINT32 Reserved;
+} MEMORY_HOB_HEADER;
+
+////
+//// Functions
+////
+EFI_STATUS
+EFIAPI
+GetEepromDataHobData (VOID);
+
+EFI_STATUS
+EFIAPI
+SetEepromDataHobData (VOID);
+
+#endif // _EEPROM_DATA_MEMORY_LIB_
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/Memory/HobData.c b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/Memory/HobData.c
new file mode 100644
index 0000000000..03e263e8d8
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/Memory/HobData.c
@@ -0,0 +1,142 @@
+/** @file
+ Memory EEPROM raw data library instance.
+
+ Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
+
+ 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 "EepromDataMemoryLib.h"
+#include <PiDxe.h>
+#include <Library/HobLib.h>
+
+EFI_STATUS
+EFIAPI
+GetEepromDataHobData (VOID)
+{
+ UINT8 *BlockData;
+ BOOLEAN BlockFound;
+ UINT16 BlockNumber;
+ UINT32 BlockSize;
+ UINT8 *Buffer;
+ EFI_HOB_GUID_TYPE *GuidHobPtr;
+ UINT16 LastBlockNumber;
+ MEMORY_HOB_HEADER *MemoryHobHeader;
+ EFI_STATUS Status;
+
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Starting...\n", __FUNCTION__, __LINE__));
+
+ //
+ // Initialize variables
+ //
+ Buffer = NULL;
+ Status = EFI_SUCCESS;
+
+ if (PcdGetBool (PcdEepromMemoryHobPresent)) {
+ //
+ // Clear PCD values
+ //
+ PcdSet64 (PcdEepromMemoryPointer, 0);
+ PcdSet32 (PcdEepromMemorySize, 0);
+
+ //
+ // Gather HOB data into coherent chunk by looping thru the HOBs looking for the blocks in order.
+ //
+ LastBlockNumber = 0;
+ while (TRUE) {
+ //
+ // Reset to the beginning of the HOBs
+ //
+ BlockFound = FALSE;
+ GuidHobPtr = GetFirstGuidHob (&gEepromVariableGuid);
+ while (GuidHobPtr != NULL) {
+ //
+ // Get Memory HOB header pointer
+ //
+ MemoryHobHeader = GET_GUID_HOB_DATA (GuidHobPtr);
+ BlockData = (UINT8 *) MemoryHobHeader + sizeof (MEMORY_HOB_HEADER);
+ BlockNumber = MemoryHobHeader->BlockNumber;
+ BlockSize = MemoryHobHeader->BlockSize;
+
+ //
+ // Is this our block?
+ //
+ if ((LastBlockNumber == BlockNumber) && (MemoryHobHeader->Signature == MEMORY_HOB_HEADER_SIGNATURE)) {
+ //
+ // Yep. Copy existing buffer to larger buffer.
+ //
+ Buffer = EepromAllocateCopyPool (PcdGet32 (PcdEepromMemorySize) + BlockSize, (UINT8 *) PcdGet64 (PcdEepromMemoryPointer));
+ if (Buffer == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Unable to allocate buffer!\n", __FUNCTION__, __LINE__));
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+
+ //
+ // Append new data
+ //
+ CopyMem (Buffer + PcdGet32 (PcdEepromMemorySize), BlockData, BlockSize);
+
+ //
+ // Free old buffer and update PCDs
+ //
+ if (PcdGet64 (PcdEepromMemoryPointer) != 0) {
+ //
+ // Buffer exists. Free it.
+ //
+ EepromFreePool ((UINT8 *) (UINTN) PcdGet64 (PcdEepromMemoryPointer));
+ }
+ BlockSize += PcdGet32 (PcdEepromMemorySize);
+ PcdSet64 (PcdEepromMemoryPointer, (UINTN) Buffer);
+ PcdSet32 (PcdEepromMemorySize, BlockSize);
+
+ //
+ // Increment counter and set flag
+ //
+ LastBlockNumber++;
+ BlockFound = TRUE;
+ break;
+ }
+
+ //
+ // Skip past present HOB to get next HOB
+ //
+ GuidHobPtr = GET_NEXT_HOB (GuidHobPtr);
+ GuidHobPtr = GetNextGuidHob (&gEepromVariableGuid, GuidHobPtr);
+ }
+ if (!BlockFound) {
+ //
+ // We're done. Bail.
+ //
+ break;
+ }
+ }
+
+ //
+ // Toggle flag.
+ //
+ PcdSetBool (PcdEepromMemoryHobPresent, FALSE);
+ }
+
+Exit:
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+SetEepromDataHobData (VOID)
+{
+ //
+ // Not supported in DXE.
+ //
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Starting...\n", __FUNCTION__, __LINE__));
+ return EFI_UNSUPPORTED;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/Memory/HobDataPei.c b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/Memory/HobDataPei.c
new file mode 100644
index 0000000000..e975d11bf0
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/Memory/HobDataPei.c
@@ -0,0 +1,123 @@
+/** @file
+ Memory EEPROM raw data library instance.
+
+ Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
+
+ 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 "EepromDataMemoryLib.h"
+#include <PiPei.h>
+#include <Library/HobLib.h>
+
+EFI_STATUS
+EFIAPI
+GetEepromDataHobData (VOID)
+{
+ //
+ // Not supported in PEI.
+ //
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Starting...\n", __FUNCTION__, __LINE__));
+ return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+EFIAPI
+SetEepromDataHobData (VOID)
+{
+ UINT8 *BlockData;
+ UINT16 BlockNumber;
+ UINT16 BlockSize;
+ UINT8 *ImageData;
+ UINT32 ImageSize;
+ MEMORY_HOB_HEADER *MemoryHobHeader;
+ UINT32 Offset;
+ EFI_STATUS Status;
+
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Starting...\n", __FUNCTION__, __LINE__));
+
+ //
+ // Initialize variables
+ //
+ BlockData = NULL;
+ ImageData = (UINT8 *) (UINTN) PcdGet64 (PcdEepromMemoryPointer);
+ ImageSize = PcdGet32 (PcdEepromMemorySize);
+ Status = EFI_SUCCESS;
+
+ if (!PcdGetBool (PcdEepromMemoryHobPresent) && (ImageData != NULL) && (ImageSize != 0)) {
+ //
+ // No HOB yet. Create one.
+ //
+ BlockNumber = 0;
+ Offset = 0;
+ while (ImageSize > 0) {
+ //
+ // Adjust block size
+ //
+ if (ImageSize > MEMORY_HOB_MAX_DATA_SIZE) {
+ BlockSize = MEMORY_HOB_MAX_DATA_SIZE;
+ } else {
+ BlockSize = (UINT16) ImageSize;
+ }
+
+ //
+ // Create Block data buffer
+ //
+ BlockData = EepromFreePool (BlockData);
+ BlockData = EepromAllocatePool (BlockSize + sizeof (MEMORY_HOB_HEADER));
+ if (BlockData == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Unable to allocate buffer!\n", __FUNCTION__, __LINE__));
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+
+ //
+ // Setup header
+ //
+ MemoryHobHeader = (MEMORY_HOB_HEADER *) BlockData;
+ MemoryHobHeader->Signature = MEMORY_HOB_HEADER_SIGNATURE;
+ MemoryHobHeader->Version = MEMORY_HOB_HEADER_VERSION;
+ MemoryHobHeader->BlockNumber = BlockNumber;
+ MemoryHobHeader->BlockSize = BlockSize;
+ MemoryHobHeader->Reserved = 0x00000000;
+
+ //
+ // Copy data into buffer
+ //
+ CopyMem (
+ (BlockData + sizeof (MEMORY_HOB_HEADER)),
+ (ImageData + Offset),
+ (BlockSize + sizeof (MEMORY_HOB_HEADER))
+ );
+
+ //
+ // Create GUID HOB
+ //
+ BuildGuidDataHob (&gEepromVariableGuid, BlockData, BlockSize);
+
+ //
+ // Adjust pointers and such
+ //
+ Offset += BlockSize;
+ BlockNumber += 1;
+ ImageSize -= BlockSize;
+ }
+
+ //
+ // Toggle flag.
+ //
+ PcdSetBool (PcdEepromMemoryHobPresent, TRUE);
+ }
+
+Exit:
+ BlockData = EepromFreePool (BlockData);
+ return Status;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/MemoryAllocation.c b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/MemoryAllocation.c
new file mode 100644
index 0000000000..4d4b9ed322
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/MemoryAllocation.c
@@ -0,0 +1,67 @@
+/** @file
+ Common EEPROM memory allocation code.
+
+ Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+
+ 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 "EepromDataLib.h"
+
+#include <Library/MemoryAllocationLib.h>
+
+//
+// Desc: Copies the contents of an existing memory pool into a new memory pool of equal or greater size.
+// Variables: Size Size of the pool to copy existing pool into
+// SourcePointer Pointer to the source buffer to copy
+// Return: Pointer Pointer to your copy of the pool
+//
+VOID*
+EFIAPI
+EepromAllocateCopyPool (
+ IN UINTN Size,
+ IN VOID *SourcePointer
+ )
+{
+ return AllocateCopyPool (Size, SourcePointer);
+}
+
+//
+// Desc: Creates a new memory pool.
+// Variables: Size Size of the pool requested
+// Return: Pointer Pointer the new pool
+//
+VOID*
+EFIAPI
+EepromAllocatePool (
+ IN UINTN Size
+ )
+{
+ return AllocateZeroPool (Size);
+}
+
+//
+// Desc: Frees a memory pool.
+// Variables: Pointer Pointer to the beginning of the pool to be freed
+// Return: Pointer NULL
+//
+VOID*
+EFIAPI
+EepromFreePool (
+ IN VOID *Pointer
+ )
+{
+ if (Pointer != NULL) {
+ FreePool (Pointer);
+ }
+
+ return NULL;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/MemoryAllocationPei.c b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/MemoryAllocationPei.c
new file mode 100644
index 0000000000..250666ffbc
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/MemoryAllocationPei.c
@@ -0,0 +1,481 @@
+/** @file
+ Common EEPROM memory allocation code. This is necessary in PEI
+ becuase PEI doesn't have working FreePool code and this code
+ uses alot of pool allocation for temporary storage.
+
+ Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+
+ 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 "EepromDataLib.h"
+
+#include <PiPei.h>
+#include <Library/EepromLib.h>
+#include <Library/HobLib.h>
+
+//
+// Desc: Frees an existing EEPROM memory allocation from the EEPROM heap.
+// Variables: HobPointer Pointer to the EEPROM memory allocation HOB
+// Offset Pointer to the beginning of the pool to free
+// Return: Status EFI_SUCCESS - Successfully freed pool
+// EFI_INVALID_PARAMETER - Invalid input parameter
+//
+EFI_STATUS
+EFIAPI
+ClearEepromAllocation (
+ IN EEPROM_ALLOCATION_STRUCT *Header,
+ IN VOID *Offset
+ )
+{
+ UINT8 bit;
+ UINT16 ByteCount;
+ UINTN HeapPointer;
+ UINTN index;
+ UINT16 Size;
+ UINTN StartIndex;
+ EFI_STATUS Status;
+
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Starting...\n", __FUNCTION__, __LINE__));
+
+ //
+ // Initialize variables
+ //
+ HeapPointer = (UINTN) Header + sizeof (EEPROM_ALLOCATION_STRUCT);
+ HeapPointer += 0x10 - (HeapPointer % 0x10);
+ Size = 0;
+ StartIndex = ((UINTN) Offset - HeapPointer) / 0x10;
+ Status = EFI_SUCCESS;
+
+ //
+ // Sanity checks
+ //
+ if ((Header == NULL) || (Offset == NULL)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Header or Offset is NULL!\n", __FUNCTION__, __LINE__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ if (HeapPointer > (UINTN) Offset) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: HeapPointer > Offset!\n", __FUNCTION__, __LINE__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ if (((UINTN) Offset % 0x10) != 0) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Offset not paragraph aligned [%08x]!\n", __FUNCTION__, __LINE__, Offset));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+
+ //
+ // Clear flags
+ //
+ for (index = StartIndex; index < (MAX_EEPROM_ALLOCATION_FLAG * 8); index++) {
+ ByteCount = (UINT16) (index / 8);
+ bit = (1 << (index % 8));
+ // Check usage flag
+ if (Header->UsageFlag[ByteCount] & bit) {
+ // Used. Reset flag
+ Header->UsageFlag[ByteCount] &= ~bit;
+ Size++;
+ } else {
+ // Available. End of this allocation, bail.
+ break;
+ }
+ }
+
+Exit:
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Header = %08x\n", __FUNCTION__, __LINE__, Header));
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Size = %08x\n", __FUNCTION__, __LINE__, Size * 0x10));
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Heap = %08x\n", __FUNCTION__, __LINE__, HeapPointer));
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Start = %08x\n", __FUNCTION__, __LINE__, StartIndex));
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Offset = %08x\n", __FUNCTION__, __LINE__, Offset));
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - Ending with %r\n", __FUNCTION__, __LINE__, Status));
+ }
+ return Status;
+}
+
+//
+// Desc: Dumps the EEPROM memory allocation status.
+// Variables: HobPointer Pointer to the EEPROM memory allocation HOB
+// Return: NA
+//
+VOID
+EFIAPI
+DumpAllocationTable (
+ IN EEPROM_ALLOCATION_STRUCT *Header
+ )
+{
+ UINT8 bit;
+ UINT16 ByteCount;
+ UINTN count;
+ UINTN index;
+
+ if (mEepromDataLibDebugFlag) {
+ //
+ // Loop thru and display blocks
+ //
+ count = 0;
+ for (index = 0; index < (MAX_EEPROM_ALLOCATION_FLAG * 8); index++) {
+ ByteCount = (UINT16) (index / 8);
+ bit = (1 << (index % 8));
+ if (count == 0) {
+ DEBUG ((DEBUG_INFO, "%04x - ", index));
+ }
+ // Check usage flag
+ if (Header->UsageFlag[ByteCount] & bit) {
+ // Used.
+ DEBUG ((DEBUG_INFO, "*"));
+ } else {
+ // Available
+ DEBUG ((DEBUG_INFO, " "));
+ }
+ count++;
+ if (count == (8 * 8)) {
+ DEBUG ((DEBUG_INFO, "\n"));
+ count = 0;
+ }
+ }
+ }
+}
+
+//
+// Desc: Finds the first fit for the requested pool size.
+// Variables: HobPointer Pointer to the EEPROM memory allocation HOB
+// Size Size of the requested pool
+// Return: Pointer Pointer to the pool or NULL if no room
+//
+VOID*
+EFIAPI
+FindEepromAllocationOffset (
+ IN EEPROM_ALLOCATION_STRUCT *Header,
+ IN UINT16 Size
+ )
+{
+ UINT8 bit;
+ UINTN beginingIndex;
+ UINT16 ByteCount;
+ UINT16 CurrentSize;
+ UINTN HeapPointer;
+ UINTN index;
+ VOID *ReturnPointer;
+ UINTN StartIndex;
+
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Starting...\n", __FUNCTION__, __LINE__));
+
+ //
+ // Initialize variables
+ //
+ CurrentSize = 0;
+ HeapPointer = (UINTN) Header + sizeof (EEPROM_ALLOCATION_STRUCT);
+ HeapPointer += 0x10 - (HeapPointer % 0x10);
+ ReturnPointer = NULL;
+ StartIndex = 0;
+
+ //
+ // Sanity checks
+ //
+ if (Header == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Header is NULL!\n", __FUNCTION__, __LINE__));
+ goto Exit;
+ }
+ if ((Size == 0) || (Size > MAX_EEPROM_ALLOCATION_SIZE)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Size is either 0 or > %08x!\n", __FUNCTION__, __LINE__, MAX_EEPROM_ALLOCATION_SIZE));
+ goto Exit;
+ }
+
+ //
+ // Loop thru flags looking for enough to make up size
+ // - Size is in flag units already
+ //
+ if (Size < 0x20) {
+ // For small allocations
+ beginingIndex = 0;
+ } else {
+ // For larger allocations
+ beginingIndex = 0x20;
+ }
+ for (index = beginingIndex; index < (MAX_EEPROM_ALLOCATION_FLAG * 8); index++) {
+ ByteCount = (UINT16) (index / 8);
+ bit = (1 << (index % 8));
+ // Check usage flag
+ if (Header->UsageFlag[ByteCount] & bit) {
+ // Used. Reset count.
+ CurrentSize = 0;
+ } else {
+ // Available
+ if ((index == 0) || ((CurrentSize == 1) && (index != 1))) {
+ // Block after empty block, except first block
+ StartIndex = index;
+ }
+ CurrentSize++;
+ }
+ // Do we have enough room?
+ if (CurrentSize > Size) {
+ // Yep. Set usage flags, leaving the last one cleared.
+ for (index = StartIndex; index < StartIndex + Size; index++) {
+ ByteCount = (UINT16) (index / 8);
+ bit = (1 << (index % 8));
+ Header->UsageFlag[ByteCount] |= bit;
+ }
+ // Set pointer
+ ReturnPointer = (VOID *) (HeapPointer + (StartIndex * 0x10));
+ // Bail
+ break;
+ }
+ }
+
+ //
+ // Display error if no room
+ //
+ if (ReturnPointer == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: No room on heap!\n", __FUNCTION__, __LINE__));
+ }
+
+Exit:
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Header = %08x\n", __FUNCTION__, __LINE__, Header));
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Size = %08x\n", __FUNCTION__, __LINE__, Size * 0x10));
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Heap = %08x\n", __FUNCTION__, __LINE__, HeapPointer));
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Start = %08x\n", __FUNCTION__, __LINE__, StartIndex));
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Offset = %08x\n", __FUNCTION__, __LINE__, ReturnPointer));
+ return ReturnPointer;
+}
+
+//
+// Desc: Finds or allocates a memory buffer for the PEI EEPROM code to use as a heap.
+// Variables: NA
+// Return: Pointer Eeprom Memory HOB
+//
+EEPROM_ALLOCATION_STRUCT*
+EFIAPI
+GetEepromMemoryHob (VOID)
+{
+ EEPROM_ALLOCATION_STRUCT AllocationHeader;
+ EEPROM_ALLOCATION_STRUCT *HeaderPointer;
+ EFI_HOB_GUID_TYPE *GuidHobPtr;
+
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Starting...\n", __FUNCTION__, __LINE__));
+
+ //
+ // If HOB already there, just return pointer to it
+ //
+ GuidHobPtr = GetFirstGuidHob (&gEepromVariableGuid);
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - GuidHobPtr = %08x\n", __FUNCTION__, __LINE__, GuidHobPtr));
+ while (GuidHobPtr != NULL) {
+ //
+ // Get Memory HOB header pointer
+ //
+ HeaderPointer = GET_GUID_HOB_DATA (GuidHobPtr);
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - HeaderPointer = %08x\n", __FUNCTION__, __LINE__, HeaderPointer));
+ //
+ // Is this our block?
+ //
+ if (HeaderPointer->Signature == ALLOCATION_HOB_HEADER_SIGNATURE) {
+ //
+ // Yep
+ //
+ goto Exit;
+ }
+ //
+ // Skip past present HOB to get next HOB
+ //
+ GuidHobPtr = GET_NEXT_HOB (GuidHobPtr);
+ GuidHobPtr = GetNextGuidHob (&gEepromVariableGuid, GuidHobPtr);
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - GuidHobPtr = %08x\n", __FUNCTION__, __LINE__, GuidHobPtr));
+ }
+
+ //
+ // Create HOB
+ //
+ DisplayStackPointer (__FUNCTION__, __LINE__);
+ ZeroMem (&AllocationHeader, sizeof (EEPROM_ALLOCATION_STRUCT));
+ AllocationHeader.Signature = ALLOCATION_HOB_HEADER_SIGNATURE;
+ HeaderPointer = BuildGuidDataHob (&gEepromVariableGuid, &AllocationHeader, MAX_EEPROM_HOB_SIZE);
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - HeaderPointer = %08x\n", __FUNCTION__, __LINE__, HeaderPointer));
+ DisplayStackPointer (__FUNCTION__, __LINE__);
+
+Exit:
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - AllocationHob @ %08x\n", __FUNCTION__, __LINE__, HeaderPointer));
+ return HeaderPointer;
+}
+
+//
+// Desc: Copies the contents of an existing memory pool into a new memory pool of equal or greater size.
+// Variables: Size Size of the pool to copy existing pool into
+// SourcePointer Pointer to the source buffer to copy
+// Return: Pointer Pointer to your copy of the pool
+//
+VOID*
+EFIAPI
+EepromAllocateCopyPool (
+ IN UINTN Size,
+ IN VOID *SourcePointer
+ )
+{
+ VOID *PoolPointer;
+
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Starting...\n", __FUNCTION__, __LINE__));
+
+ //
+ // Sanity checks
+ //
+ if (SourcePointer == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: SourcePointer is NULL!\n", __FUNCTION__, __LINE__));
+ PoolPointer = NULL;
+ goto Exit;
+ }
+ if ((Size == 0) || (Size > MAX_EEPROM_ALLOCATION_SIZE)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Size is either 0 or > %08x!\n", __FUNCTION__, __LINE__, MAX_EEPROM_ALLOCATION_SIZE));
+ PoolPointer = NULL;
+ goto Exit;
+ }
+
+ //
+ // Get pool for copy
+ //
+ PoolPointer = EepromAllocatePool (Size);
+ if (PoolPointer == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: PoolPointer is NULL!\n", __FUNCTION__, __LINE__));
+ goto Exit;
+ }
+
+ //
+ // Copy source into new pool
+ //
+ CopyMem (PoolPointer, SourcePointer, Size);
+
+Exit:
+ return PoolPointer;
+}
+
+//
+// Desc: Creates a new memory pool.
+// Variables: Size Size of the pool requested
+// Return: Pointer Pointer the new pool
+//
+VOID*
+EFIAPI
+EepromAllocatePool (
+ IN UINTN Size
+ )
+{
+ EEPROM_ALLOCATION_STRUCT *AllocationHobHeader;
+ UINT16 ConvertedSize;
+ UINT16 PoolSize;
+ VOID *ReturnPointer;
+
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Starting...\n", __FUNCTION__, __LINE__));
+
+ //
+ // Sanity checking
+ //
+ if ((Size == 0) || (Size > MAX_EEPROM_ALLOCATION_SIZE)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Size is either 0 or > %08x!\n", __FUNCTION__, __LINE__, MAX_EEPROM_ALLOCATION_SIZE));
+ ReturnPointer = NULL;
+ goto Exit;
+ }
+
+ //
+ // Convert size to paragraphs and add one for the guard
+ //
+ ConvertedSize = (UINT16) (Size & 0xFFFF);
+ PoolSize = ConvertedSize / 0x10;
+ if ((ConvertedSize % 0x10) > 0) {
+ //
+ // Size it up to the next paragraph
+ //
+ PoolSize++;
+ }
+
+ //
+ // Get or create EEPROM allocation pool HOB
+ //
+ AllocationHobHeader = GetEepromMemoryHob ();
+ if (AllocationHobHeader == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: AllocationHobHeader is NULL!\n", __FUNCTION__, __LINE__));
+ ReturnPointer = NULL;
+ goto Exit;
+ }
+
+ //
+ // Find first available fit and set usage flags
+ //
+ ReturnPointer = FindEepromAllocationOffset (AllocationHobHeader, PoolSize);
+ if (ReturnPointer == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: ReturnPointer is NULL!\n", __FUNCTION__, __LINE__));
+ goto Exit;
+ }
+
+ //
+ // Zero pool
+ //
+ ZeroMem (ReturnPointer, Size);
+
+ //
+ // Dump pool
+ //
+ DumpAllocationTable (AllocationHobHeader);
+
+Exit:
+ return ReturnPointer;
+}
+
+//
+// Desc: Frees a memory pool.
+// Variables: Pointer Pointer to the beginning of the pool to be freed
+// Return: Pointer NULL
+//
+VOID*
+EFIAPI
+EepromFreePool (
+ IN VOID *Pointer
+ )
+{
+ EEPROM_ALLOCATION_STRUCT *AllocationHobHeader;
+ EFI_STATUS Status;
+
+ if (mEepromDataLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Starting...\n", __FUNCTION__, __LINE__));
+
+ //
+ // Get EEPROM allocation pool HOB
+ //
+ AllocationHobHeader = GetEepromMemoryHob ();
+ if (AllocationHobHeader == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: AllocationHobHeader is NULL!\n", __FUNCTION__, __LINE__));
+ goto Exit;
+ }
+
+ //
+ // Sanity checks
+ //
+ if (Pointer == NULL) {
+ // Nothing to do. Bail.
+ goto Exit;
+ }
+ if ((UINTN) Pointer > ((UINTN) AllocationHobHeader + MAX_EEPROM_ALLOCATION_SIZE)) {
+ // Past our heap. Bail.
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: This is not our pool [%08x]!\n", __FUNCTION__, __LINE__, Pointer));
+ goto Exit;
+ }
+
+ //
+ // Find allocation and clear usage flags
+ //
+ Status = ClearEepromAllocation (AllocationHobHeader, Pointer);
+
+ //
+ // Dump pool
+ //
+ DumpAllocationTable (AllocationHobHeader);
+
+Exit:
+ return NULL;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/Null/EepromDataNullLib.c b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/Null/EepromDataNullLib.c
new file mode 100644
index 0000000000..6ac9a16b57
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/Null/EepromDataNullLib.c
@@ -0,0 +1,67 @@
+/** @file
+ Null EEPROM raw data library instance.
+
+ Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
+
+ 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 "EepromDataNullLib.h"
+
+//
+// Desc: Reads from the EEPROM and copies to the passed in buffer.
+// Variables: Offset Start copying from the offset
+// Size Size of the buffer and the number of bytes to copy
+// - If set to 0, then return size of EEPROM binary
+// Buffer Storage buffer for the copied data from the EEPROM
+// FunctionInfo Pointer to function specific data
+// Return: EFI_SUCCESS Data copied successfully
+// EFI_UNSUPPORTED This function is not supported
+// EFI_INVALID_PARAMETER One of the parameters is invalid
+// EFI_NOT_READY Called before all necessary protocols available
+// EFI_DEVICE_ERROR Communication error with device
+//
+EFI_STATUS
+EFIAPI
+ReadEepromNull (
+ IN UINT32 Offset,
+ IN OUT UINT32 *Size,
+ IN OUT UINT8 *Buffer,
+ IN OUT VOID *FunctionInfo
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+//
+// Desc: Writes to the EEPROM and copies to the passed in buffer.
+// Variables: Offset Start copying from the offset
+// Size Size of the buffer and the number of bytes to copy
+// - If set to 0, then return size of EEPROM binary
+// Buffer Data to be copied to the EEPROM
+// FunctionInfo Pointer to function specific data
+// Return: EFI_SUCCESS Data copied successfully
+// EFI_UNSUPPORTED This function is not supported
+// EFI_INVALID_PARAMETER One of the parameters is invalid
+// EFI_NOT_READY Called before all necessary protocols available
+// EFI_DEVICE_ERROR Communication error with device
+//
+EFI_STATUS
+EFIAPI
+WriteEepromNull (
+ IN UINT32 Offset,
+ IN OUT UINT32 *Size,
+ IN OUT UINT8 *Buffer,
+ IN OUT VOID *FunctionInfo
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/Null/EepromDataNullLib.h b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/Null/EepromDataNullLib.h
new file mode 100644
index 0000000000..255cdec9d1
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromDataLib/Null/EepromDataNullLib.h
@@ -0,0 +1,24 @@
+/** @file
+ Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
+
+ 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 _EEPROM_DATA_NULL_LIB_
+#define _EEPROM_DATA_NULL_LIB_
+////
+//// Header files
+////
+#include <Uefi.h>
+
+#include <Library/DebugLib.h>
+#include <Library/EepromDataLib.h>
+
+#endif // _EEPROM_DATA_NULL_LIB_
--
2.14.1.windows.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [Patch][edk2-platforms/devel-IntelAtomProcessorE3900 4/5] Common EEPROM library instance.
2018-07-23 2:39 [Patch][edk2-platforms/devel-IntelAtomProcessorE3900 1/5] Add EepromApp zwei4
2018-07-23 2:39 ` [Patch][edk2-platforms/devel-IntelAtomProcessorE3900 3/5] Library producing EEPROM raw data functionality zwei4
@ 2018-07-23 2:39 ` zwei4
2018-07-23 2:39 ` [Patch][edk2-platforms/devel-IntelAtomProcessorE3900 5/5] EEPROM header files zwei4
2 siblings, 0 replies; 4+ messages in thread
From: zwei4 @ 2018-07-23 2:39 UTC (permalink / raw)
To: edk2-devel; +Cc: David Wei, Kelly Steele, Mike Wu, Mang Guo
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: David Wei <david.wei@intel.com>
CC: Kelly Steele <kelly.steele@intel.com>
CC: Mike Wu <mike.wu@intel.com>
CC: Mang Guo <mang.guo@intel.com>
---
.../Common/Features/Eeprom/EepromLib/EepromLib.c | 1011 ++++++++++++++++++++
.../Common/Features/Eeprom/EepromLib/EepromLib.h | 76 ++
.../Common/Features/Eeprom/EepromLib/EepromLib.inf | 63 ++
.../Features/Eeprom/EepromLib/EepromNullLib.inf | 36 +
.../Features/Eeprom/EepromLib/EepromPeiLib.inf | 62 ++
.../Features/Eeprom/EepromLib/Null/EepromNullLib.c | 82 ++
.../Features/Eeprom/EepromLib/Null/EepromNullLib.h | 26 +
.../Eeprom/EepromLib/Pei/ValidateHashPei.c | 251 +++++
.../Features/Eeprom/EepromLib/ValidateHash.c | 399 ++++++++
9 files changed, 2006 insertions(+)
create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/EepromLib.c
create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/EepromLib.h
create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/EepromLib.inf
create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/EepromNullLib.inf
create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/EepromPeiLib.inf
create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/Null/EepromNullLib.c
create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/Null/EepromNullLib.h
create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/Pei/ValidateHashPei.c
create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/ValidateHash.c
diff --git a/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/EepromLib.c b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/EepromLib.c
new file mode 100644
index 0000000000..6ab06da2be
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/EepromLib.c
@@ -0,0 +1,1011 @@
+/** @file
+ Common EEPROM library instance.
+
+ Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
+
+ 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 "EepromLib.h"
+
+BOOLEAN *gImageValidFlag;
+UINT32 mCrcTable[256];
+BOOLEAN mCrcInitFlag = FALSE;
+BOOLEAN mEepromLibDebugFlag = TRUE;
+
+/**
+ This internal function reverses bits for 32bit data.
+
+ @param Value The data to be reversed.
+
+ @return Data reversed.
+
+**/
+UINT32
+EFIAPI
+ReverseBits (
+ UINT32 Value
+ )
+{
+ UINTN Index;
+ UINT32 NewValue;
+
+ NewValue = 0;
+ for (Index = 0; Index < 32; Index++) {
+ if ((Value & (1 << Index)) != 0) {
+ NewValue = NewValue | (1 << (31 - Index));
+ }
+ }
+
+ return NewValue;
+}
+
+/**
+ Initialize CRC32 table.
+
+**/
+VOID
+EFIAPI
+InitializeCrc32Table (
+ VOID
+ )
+{
+ UINTN TableEntry;
+ UINTN Index;
+ UINT32 Value;
+
+ for (TableEntry = 0; TableEntry < 256; TableEntry++) {
+ Value = ReverseBits ((UINT32) TableEntry);
+ for (Index = 0; Index < 8; Index++) {
+ if ((Value & 0x80000000) != 0) {
+ Value = (Value << 1) ^ 0x04C11DB7;
+ } else {
+ Value = Value << 1;
+ }
+ }
+
+ mCrcTable[TableEntry] = ReverseBits (Value);
+ }
+ mCrcInitFlag = TRUE;
+}
+
+/*++
+
+Routine Description:
+
+ The CalculateCrc32 routine.
+
+Arguments:
+
+ Data - The buffer contaning the data to be processed
+ DataSize - The size of data to be processed
+ CrcOut - A pointer to the caller allocated UINT32 that on
+ contains the CRC32 checksum of Data
+
+Returns:
+
+ EFI_SUCCESS - Calculation is successful.
+ EFI_INVALID_PARAMETER - Data / CrcOut = NULL, or DataSize = 0
+
+--*/
+EFI_STATUS
+EFIAPI
+CalculateCrc32 (
+ IN UINT8 *Data,
+ IN UINTN DataSize,
+ IN OUT UINT32 *CrcOut
+ )
+{
+ UINT32 Crc;
+ UINTN Index;
+ UINT8 *Ptr;
+
+ if (mEepromLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Starting...\n", __FUNCTION__, __LINE__));
+
+ // Sanity checks
+ if ((DataSize == 0) || (Data == NULL) || (CrcOut == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Table initialized?
+ if (!mCrcInitFlag) InitializeCrc32Table ();
+
+ Crc = 0xFFFFFFFF;
+ for (Index = 0, Ptr = Data; Index < DataSize; Index++, Ptr++) {
+ Crc = (Crc >> 8) ^ mCrcTable[(UINT8) Crc ^ *Ptr];
+ }
+
+ *CrcOut = Crc ^ 0xFFFFFFFF;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+EepromLibNemToMemory (VOID)
+{
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+EraseEeprom (
+ IN UINT8 LibraryIndex
+ )
+{
+ UINT8 *Buffer;
+ EEPROM_FUNCTION_INFO EepromInfo;
+ UINT32 Size;
+ EFI_STATUS Status;
+
+ if (mEepromLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Starting...\n", __FUNCTION__, __LINE__));
+
+ //
+ // Initialize variables
+ //
+ ZeroMem (&EepromInfo, sizeof (EEPROM_FUNCTION_INFO));
+ EepromInfo.Bus = PcdGet8 (PcdEepromBus);
+ EepromInfo.Address = PcdGet8 (PcdEepromAddress);
+ EepromInfo.LibraryIndex = EEPROM_EEPROM;
+ Size = sizeof (GENERIC_HEADER);
+ Buffer = EepromAllocatePool (Size);
+
+ //
+ // Sanity checks
+ //
+ if (LibraryIndex >= EEPROM_DATA_LIBRARY_INDEX_MAX) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Library index is larger than %d!\n", __FUNCTION__, __LINE__, EEPROM_DATA_LIBRARY_INDEX_MAX - 1));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ if (Buffer == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Buffer pointer is NULL!\n", __FUNCTION__, __LINE__));
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+
+ //
+ // Try to erase the first header, thereby invalidating the image.
+ //
+ Status = WriteEeprom (LibraryIndex, 0, &Size, Buffer, &EepromInfo);
+ if (EFI_ERROR (Status)) {
+ //
+ // Failed, so bail.
+ //
+ goto Exit;
+ }
+
+ //
+ // Clear the valid status for this image.
+ //
+ gImageValidFlag[LibraryIndex] = FALSE;
+
+Exit:
+ //
+ // Free resources
+ //
+ Buffer = EepromFreePool (Buffer);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - Ending with %r\n", __FUNCTION__, __LINE__, Status));
+ }
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+GetEepromStructure (
+ IN UINT8 LibraryIndex,
+ IN OUT CHAR8 Signature[EEPROM_SIGNATURE_SIZE],
+ IN OUT UINT8 **Buffer,
+ IN OUT UINT32 *Size
+ )
+{
+ GENERIC_HEADER *EepromHeader;
+ UINT32 Index;
+ EFI_STATUS Status;
+
+ if (mEepromLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Starting...\n", __FUNCTION__, __LINE__));
+
+ //
+ // Initialize variables
+ //
+ EepromHeader = NULL;
+ Status = EFI_SUCCESS;
+
+ //
+ // Sanity checks
+ //
+ if (LibraryIndex >= EEPROM_DATA_LIBRARY_INDEX_MAX) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Library index is larger than %d!\n", __FUNCTION__, __LINE__, EEPROM_DATA_LIBRARY_INDEX_MAX - 1));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ if (Signature == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Signature pointer is NULL!\n", __FUNCTION__, __LINE__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ if (Buffer == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Buffer pointer is NULL!\n", __FUNCTION__, __LINE__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ if (Size == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Size pointer is NULL!\n", __FUNCTION__, __LINE__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+
+ //
+ // Start at the beginning structure and loop thru the image looking for the requested structure
+ //
+ Index = 0;
+ while (!EFI_ERROR (Status)) {
+ //
+ // Make sure buffer is empty
+ //
+ *Buffer = EepromFreePool (*Buffer);
+ Status = GetNextEepromStructure (LibraryIndex, &Index, Buffer, Size);
+ if (*Size != 0) {
+ //
+ // The buffer isn't empty
+ //
+ EepromHeader = (GENERIC_HEADER *) *Buffer;
+ if (AsciiStrnCmp (EepromHeader->signature, Signature, AsciiStrLen (Signature)) == 0) {
+ //
+ // This is our structure. Bail.
+ //
+ goto Exit;
+ }
+ }
+ *Buffer = EepromFreePool (*Buffer);
+ }
+
+ //
+ // Didn't find it. Error out.
+ //
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Failed to find %a structure!\n", __FUNCTION__, __LINE__, Signature));
+ Status = EFI_NOT_FOUND;
+
+Exit:
+ if (EFI_ERROR (Status)) {
+ *Buffer = EepromFreePool (*Buffer);
+ *Size = 0;
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - Ending with %r\n", __FUNCTION__, __LINE__, Status));
+ }
+ return Status;
+}
+
+UINT32
+EFIAPI
+GetImageSize (
+ IN UINT8 LibraryIndex
+ )
+{
+ EEPROM_HEADER EepromHeader;
+ EEPROM_FUNCTION_INFO EepromInfo;
+ UINT32 Size;
+ EFI_STATUS Status;
+
+ if (mEepromLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Starting...\n", __FUNCTION__, __LINE__));
+
+ //
+ // Initialize variables
+ //
+ ZeroMem (&EepromInfo, sizeof (EEPROM_FUNCTION_INFO));
+ EepromInfo.Bus = PcdGet8 (PcdEepromBus);
+ EepromInfo.Address = PcdGet8 (PcdEepromAddress);
+ EepromInfo.LibraryIndex = EEPROM_EEPROM;
+
+ //
+ // Sanity checks
+ //
+ if (LibraryIndex >= EEPROM_DATA_LIBRARY_INDEX_MAX) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Library index is larger than %d!\n", __FUNCTION__, __LINE__, EEPROM_DATA_LIBRARY_INDEX_MAX - 1));
+ Size = 0;
+ goto Exit;
+ }
+
+ //
+ // Grab $Eeprom$ structure which should be the first structure at offset 0
+ //
+ Size = sizeof (EEPROM_HEADER);
+ ZeroMem (&EepromHeader, Size);
+ Status = ReadEeprom (LibraryIndex, 0, &Size, (UINT8 *) &EepromHeader, &EepromInfo);
+ if (EFI_ERROR (Status) || (AsciiStrnCmp (EepromHeader.signature, "$Eeprom$", 8) != 0)) {
+ //
+ // Oops!
+ //
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Failed to find $Eeprom$ structure!\n", __FUNCTION__, __LINE__));
+ //
+ // Try ReadEeprom() method
+ //
+ Size = 0;
+ Status = ReadEeprom (LibraryIndex, 0, &Size, (UINT8 *) &EepromHeader, &EepromInfo);
+ if ((Status != EFI_BUFFER_TOO_SMALL) || (Status != EFI_SUCCESS)) {
+ //
+ // Didn't find size.
+ //
+ Status = EFI_NOT_FOUND;
+ goto Exit;
+ }
+ }
+
+ //
+ // Return size
+ //
+ Size = EepromHeader.structlength;
+ if (mEepromLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Image size = %08x\n", __FUNCTION__, __LINE__, Size));
+
+Exit:
+ return Size;
+}
+
+EFI_STATUS
+EFIAPI
+GetNextEepromStructure (
+ IN UINT8 LibraryIndex,
+ IN OUT UINT32 *Index,
+ IN OUT UINT8 **Buffer,
+ IN OUT UINT32 *Size
+ )
+{
+ CHAR8 *AsciiString;
+ EEPROM_FUNCTION_INFO EepromInfo;
+ UINT32 ImageSize;
+ UINT32 Offset;
+ EFI_STATUS Status;
+ GENERIC_HEADER Structure;
+ UINT8 *TempBuffer;
+ UINT32 TempSize;
+
+ if (mEepromLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Starting...\n", __FUNCTION__, __LINE__));
+
+ //
+ // Initialize variables
+ //
+ ZeroMem (&EepromInfo, sizeof (EEPROM_FUNCTION_INFO));
+ EepromInfo.Bus = PcdGet8 (PcdEepromBus);
+ EepromInfo.Address = PcdGet8 (PcdEepromAddress);
+ EepromInfo.LibraryIndex = EEPROM_EEPROM;
+ Status = EFI_SUCCESS;
+ TempBuffer = NULL;
+ TempSize = 0;
+
+ //
+ // Sanity checks
+ //
+ if (LibraryIndex >= EEPROM_DATA_LIBRARY_INDEX_MAX) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Library index is larger than %d!\n", __FUNCTION__, __LINE__, EEPROM_DATA_LIBRARY_INDEX_MAX - 1));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ if (Buffer == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Buffer pointer is NULL!\n", __FUNCTION__, __LINE__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ if (Size == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Size pointer is NULL!\n", __FUNCTION__, __LINE__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+
+ //
+ // Make sure the incoming buffer is empty
+ //
+ *Buffer = EepromFreePool (*Buffer);
+ *Size = 0;
+
+ //
+ // Grab the image size
+ //
+ ImageSize = GetImageSize (LibraryIndex);
+ if (ImageSize == 0) {
+ //
+ // Oops!
+ //
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Failed to get image size!\n", __FUNCTION__, __LINE__));
+ Status = EFI_NOT_FOUND;
+ goto Exit;
+ }
+
+ //
+ // Paragraph align offset
+ //
+ Offset = *Index + (*Index % 0x10);
+
+ //
+ // Sanity check to make sure we are still in the image
+ //
+ if (Offset >= ImageSize) {
+ if (mEepromLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - WARNING: Went past the end of the image!\n", __FUNCTION__, __LINE__));
+ Status = EFI_END_OF_FILE;
+ goto Exit;
+ }
+
+ //
+ // Read in the next header
+ //
+ TempSize = sizeof (GENERIC_HEADER);
+ Status = ReadEeprom (LibraryIndex, Offset, &TempSize, (UINT8 *) &Structure, &EepromInfo);
+ if (EFI_ERROR (Status)) {
+ //
+ // Got an error!
+ //
+ goto Exit;
+ }
+ //
+ // Check to see if this is a valid structure
+ //
+ if (Structure.signature[0] != '$') {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Failed to find structure signature starting with $!\n", __FUNCTION__, __LINE__));
+ Status = EFI_VOLUME_CORRUPTED;
+ goto Exit;
+ }
+
+ //
+ // This is our structure!
+ //
+ TempSize = Structure.length;
+ TempBuffer = EepromAllocatePool (TempSize);
+ if (TempBuffer == NULL) {
+ //
+ // Failed to allocate pool
+ //
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Failed to allocate pool for Buffer!\n", __FUNCTION__, __LINE__));
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+
+ //
+ // Some debug info
+ //
+ AsciiString = Structure.signature;
+ AsciiString[sizeof (Structure.signature)] = 0;
+ if (mEepromLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Structure[%04x] = %a\n", __FUNCTION__, __LINE__, Offset, AsciiString));
+
+ //
+ // Grab the structure
+ //
+ Status = ReadEeprom (LibraryIndex, Offset, &TempSize, TempBuffer, &EepromInfo);
+ if (mEepromLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - ReadEeprom() -> %r\n", __FUNCTION__, __LINE__, Status));
+ if (!EFI_ERROR (Status)) {
+ //
+ // Got a valid structure. Point Index to end of the structure..
+ //
+ *Index = Offset + TempSize;
+ //
+ // Pass out data
+ //
+ *Buffer = TempBuffer;
+ *Size = TempSize;
+ }
+
+Exit:
+ if (EFI_ERROR (Status)) {
+ TempBuffer = EepromFreePool (TempBuffer);
+ if (Status != EFI_END_OF_FILE) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - Ending with %r\n", __FUNCTION__, __LINE__, Status));
+ }
+ }
+ return Status;
+}
+
+UINT8
+EFIAPI
+GetValidEepromLibrary (
+ IN BOOLEAN CopyToMemory,
+ IN BOOLEAN MemoryInitialized
+ )
+{
+ UINT8 *EepromAutoList;
+ EEPROM_FUNCTION_INFO EepromInfo;
+ UINT8 FirstValidImage;
+ UINT8 *ImageBuffer;
+ UINT32 ImageSize;
+ UINT8 index;
+ UINT8 Library;
+ UINT32 Size;
+ EFI_STATUS Status;
+
+ if (mEepromLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Starting...\n", __FUNCTION__, __LINE__));
+
+ //
+ // Initialize variables
+ //
+ ZeroMem (&EepromInfo, sizeof (EEPROM_FUNCTION_INFO));
+ EepromAutoList = (UINT8 *) PcdGetPtr (PcdEepromAutoPriority);
+ EepromInfo.Bus = PcdGet8 (PcdEepromBus);
+ EepromInfo.Address = PcdGet8 (PcdEepromAddress);
+ EepromInfo.LibraryIndex = EEPROM_EEPROM;
+ FirstValidImage = EEPROM_NULL;
+ ImageBuffer = NULL;
+
+ //
+ // Sanity checks
+ //
+ if (EepromAutoList == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: PCD PcdEepromAutoPriority is empty!\n", __FUNCTION__, __LINE__));
+ Library = EEPROM_NULL;
+ goto Exit;
+ }
+
+ //
+ // Display current stack pointer
+ //
+ DisplayStackPointer (__FUNCTION__, __LINE__);
+
+ //
+ // Loop thru PcdEepromAutoPriority looking for a validated image.
+ //
+ index = 0;
+ while (EepromAutoList[index] != 0xFF) {
+ Library = EepromAutoList[index];
+ if (Library >= EEPROM_DATA_LIBRARY_INDEX_MAX) {
+ //
+ // We're in the weeds. Bail.
+ //
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: PCD PcdEepromAutoPriority contains invalid value!\n", __FUNCTION__, __LINE__));
+ Library = EEPROM_NULL;
+ goto Exit;
+ }
+ if (gImageValidFlag[Library]) {
+ //
+ // This library is valid, bail.
+ //
+ FirstValidImage = Library;
+ break;
+ }
+ //
+ // Point to next library
+ //
+ index++;
+ }
+ //
+ // Check to see if we need to validate and copy into memory
+ //
+ if (!CopyToMemory) {
+ //
+ // Nope. Bail.
+ //
+ goto Exit;
+ }
+ //
+ // Display current stack pointer
+ //
+ DisplayStackPointer (__FUNCTION__, __LINE__);
+ //
+ // If nothing is valid, try validating them all
+ //
+ if (FirstValidImage == EEPROM_NULL) {
+ //
+ // Couldn't find a validated image. Try validating them all.
+ //
+ index = 0;
+ while (EepromAutoList[index] != 0xFF) {
+ Library = EepromAutoList[index];
+ if (mEepromLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Trying to validate library %a...\n", __FUNCTION__, __LINE__, mEepromLibraryString[Library]));
+ Status = ValidateEeprom (Library);
+ if (mEepromLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Validating %a -> %r\n", __FUNCTION__, __LINE__, mEepromLibraryString[Library], Status));
+ if (!EFI_ERROR (Status) || (Status == EFI_MEDIA_CHANGED)) {
+ //
+ // This one is valid. Bail.
+ //
+ if (FirstValidImage == EEPROM_NULL) {
+ FirstValidImage = Library;
+ }
+ }
+ //
+ // Point to next library
+ //
+ index++;
+ }
+ }
+ //
+ // Display current stack pointer
+ //
+ DisplayStackPointer (__FUNCTION__, __LINE__);
+ //
+ // Determine which image to copy to memory
+ //
+ if (gImageValidFlag[EEPROM_MEMORY]) {
+ //
+ // Yep. Bail.
+ //
+ Library = EEPROM_MEMORY;
+ goto Exit;
+ }
+ if (gImageValidFlag[EEPROM_EEPROM]) {
+ Library = EEPROM_EEPROM;
+ }
+ if (gImageValidFlag[EEPROM_FV]) {
+ Library = EEPROM_FV;
+ }
+ if (gImageValidFlag[EEPROM_EEPROM] && gImageValidFlag[EEPROM_FV]) {
+ BOARD_INFO_TABLE *EepromBoardInfo;
+ BOARD_INFO_TABLE *FvBoardInfo;
+ EEPROM_HEADER *EepromEepromHeader;
+ EEPROM_HEADER *FvEepromHeader;
+ //
+ // Initialize variables
+ //
+ EepromBoardInfo = NULL;
+ EepromEepromHeader = NULL;
+ FvBoardInfo = NULL;
+ FvEepromHeader = NULL;
+ Library = EEPROM_NULL;
+ //
+ // Get BoardInfo records
+ //
+ Size = 0;
+ Status = GetEepromStructure (EEPROM_EEPROM, "$BrdInfo", (UINT8 **) &EepromBoardInfo, &Size);
+ if (EFI_ERROR (Status) || (Size == 0) || (EepromBoardInfo == NULL)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Failed to get EEPROM Board Info structure! (%r)\n", __FUNCTION__, __LINE__, Status));
+ Library = EEPROM_FV;
+ } else {
+ Size = 0;
+ Status = GetEepromStructure (EEPROM_FV, "$BrdInfo", (UINT8 **) &FvBoardInfo, &Size);
+ if (EFI_ERROR (Status) || (Size == 0) || (FvBoardInfo == NULL)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Failed to get FV Board Info structure! (%r)\n", __FUNCTION__, __LINE__, Status));
+ Library = EEPROM_EEPROM;
+ } else {
+ //
+ // Compare BoardInfo records
+ //
+ if ((CompareMem (EepromBoardInfo->manuname, FvBoardInfo->manuname, 16) == 0) &&
+ (CompareMem (EepromBoardInfo->brdname, FvBoardInfo->brdname, 16) == 0) &&
+ (EepromBoardInfo->boardid == FvBoardInfo->boardid) &&
+ (EepromBoardInfo->fabid == FvBoardInfo->fabid) &&
+ (EepromBoardInfo->ecid == FvBoardInfo->ecid) &&
+ (EepromBoardInfo->boardtype == FvBoardInfo->boardtype)) {
+ //
+ // Get EepromHeader records
+ //
+ Size = 0;
+ Status = GetEepromStructure (EEPROM_EEPROM, "$Eeprom$", (UINT8 **) &EepromEepromHeader, &Size);
+ if (EFI_ERROR (Status) || (Size == 0) || (EepromEepromHeader == NULL)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Failed to get EEPROM header structure! (%r)\n", __FUNCTION__, __LINE__, Status));
+ Library = EEPROM_FV;
+ } else {
+ Size = 0;
+ Status = GetEepromStructure (EEPROM_FV, "$Eeprom$", (UINT8 **) &FvEepromHeader, &Size);
+ if (EFI_ERROR (Status) || (Size == 0) || (FvEepromHeader == NULL)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Failed to get FV header structure! (%r)\n", __FUNCTION__, __LINE__, Status));
+ Library = EEPROM_EEPROM;
+ } else {
+ //
+ // Compare image versions
+ //
+ if (EepromEepromHeader->version > FvEepromHeader->version) {
+ Library = EEPROM_EEPROM;
+ } else {
+ Library = EEPROM_FV;
+ }
+ }
+ }
+ } else {
+ //
+ // FV gets priority since BoardInfo data doesn't match
+ //
+ Library = EEPROM_FV;
+ }
+ }
+ }
+ //
+ // Free resources
+ //
+ EepromBoardInfo = EepromFreePool (EepromBoardInfo);
+ EepromEepromHeader = EepromFreePool (EepromEepromHeader);
+ FvBoardInfo = EepromFreePool (FvBoardInfo);
+ FvEepromHeader = EepromFreePool (FvEepromHeader);
+ }
+ //
+ // Display current stack pointer
+ //
+ DisplayStackPointer (__FUNCTION__, __LINE__);
+ //
+ // If we don't have memory, then bail so we don't take up all of the stack space in NEM.
+ //
+ if (!MemoryInitialized) {
+ goto Exit;
+ }
+ //
+ // We have a validated image and it is not in memory. Copy it in.
+ // 1. Ask for the image size so we can allocate a large enough buffer.
+ // 2. Read the image into the buffer.
+ // 3. Write it to memory.
+ // 4. Validate the memory copy.
+ //
+ DEBUG ((DEBUG_INFO, "%a (#%4d) - Copying %a to EEPROM_MEMORY\n", __FUNCTION__, __LINE__, mEepromLibraryString[Library]));
+ ImageSize = GetImageSize (Library);
+ if (ImageSize != 0) {
+ //
+ // Something to copy
+ //
+ ImageBuffer = EepromAllocatePool (ImageSize);
+ if (ImageBuffer == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Failed to allocate pool!\n", __FUNCTION__, __LINE__));
+ } else {
+ //
+ // Read in entire image
+ //
+ Status = ReadEeprom (Library, 0, &ImageSize, ImageBuffer, &EepromInfo);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Reading image from %a returned %r!\n", __FUNCTION__, __LINE__, mEepromLibraryString[Library], Status));
+ } else {
+ //
+ // Got the image, write to memory
+ //
+ Status = WriteEeprom (EEPROM_MEMORY, 0, &ImageSize, ImageBuffer, NULL);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Writing image to %a returned %r!\n", __FUNCTION__, __LINE__, mEepromLibraryString[EEPROM_MEMORY], Status));
+ } else {
+ //
+ // Validate memory image
+ //
+ Status = ValidateEeprom (EEPROM_MEMORY);
+ if (EFI_ERROR (Status) && (Status != EFI_MEDIA_CHANGED)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Validating image returned %r!\n", __FUNCTION__, __LINE__, Status));
+ } else {
+ //
+ // Return EEPROM_MEMORY
+ //
+ Library = EEPROM_MEMORY;
+ }
+ }
+ }
+ }
+ }
+
+Exit:
+ //
+ // Free resources
+ //
+ ImageBuffer = EepromFreePool (ImageBuffer);
+ if (FirstValidImage == EEPROM_NULL) {
+ //
+ // Nothing is valid. Return default NULL.
+ //
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Failed to find a valid image in list PcdEepromAutoPriority!\n", __FUNCTION__, __LINE__));
+ Library = EEPROM_NULL;
+ }
+
+ //
+ // Display current stack pointer
+ //
+ DisplayStackPointer (__FUNCTION__, __LINE__);
+
+ if (mEepromLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Returning library %a\n", __FUNCTION__, __LINE__, mEepromLibraryString[Library]));
+ return Library;
+}
+
+EFI_STATUS
+EFIAPI
+ValidateEeprom (
+ IN UINT8 LibraryIndex
+ )
+{
+ UINT32 Count;
+ UINT32 Crc32;
+ UINT32 Crc32Size;
+ EEPROM_HEADER *EepromHeader;
+ EEPROM_FUNCTION_INFO EepromInfo;
+ UINT8 *Hash;
+ UINT32 HashSize;
+ UINT16 HashType;
+ UINT8 *ImageBuffer;
+ UINT32 ImageSize;
+ SIGNATURE_DATA *Signature;
+ UINT8 *SignedHash;
+ UINT32 SignedHashSize;
+ EFI_STATUS Status;
+ GENERIC_HEADER *Structure;
+ INTN Test;
+
+ if (mEepromLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Starting...\n", __FUNCTION__, __LINE__));
+
+ //
+ // Initialize variables
+ //
+ ZeroMem (&EepromInfo, sizeof (EEPROM_FUNCTION_INFO));
+ Crc32Size = 0;
+ EepromHeader = NULL;
+ EepromInfo.Bus = PcdGet8 (PcdEepromBus);
+ EepromInfo.Address = PcdGet8 (PcdEepromAddress);
+ EepromInfo.LibraryIndex = EEPROM_EEPROM;
+ Hash = NULL;
+ ImageBuffer = NULL;
+ SignedHash = NULL;
+ SignedHashSize = 0;
+ Status = EFI_SUCCESS;
+ Structure = NULL;
+
+ //
+ // Sanity checks
+ //
+ if (LibraryIndex >= EEPROM_DATA_LIBRARY_INDEX_MAX) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Library index is larger than %d!\n", __FUNCTION__, __LINE__, EEPROM_DATA_LIBRARY_INDEX_MAX - 1));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+
+ //
+ // Get image size
+ //
+ ImageSize = GetImageSize (LibraryIndex);
+ if (ImageSize == 0) {
+ //
+ // Oops!
+ //
+ Status = EFI_NOT_FOUND;
+ goto Exit;
+ }
+ //
+ // Get a buffer to hold the image
+ //
+ ImageBuffer = EepromAllocatePool (ImageSize);
+ if (ImageBuffer == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Unable to allocate 0x%08x bytes for the image buffer!\n", __FUNCTION__, __LINE__, ImageSize));
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+ //
+ // Read in the image
+ //
+ Status = ReadEeprom (LibraryIndex, 0, &ImageSize, ImageBuffer, &EepromInfo);
+ if (EFI_ERROR (Status)) {
+ //
+ // Oops!!!
+ //
+ goto Exit;
+ }
+ EepromHeader = (EEPROM_HEADER *) ImageBuffer;
+ //
+ // Verify structure order
+ //
+ Count = 0;
+ Structure = (GENERIC_HEADER *) ImageBuffer;
+ while ((UINT8 *) Structure < (UINT8 *) (ImageBuffer + ImageSize)) {
+ //
+ // Increment count
+ //
+ Count++;
+ //
+ // Sanity check header
+ //
+ if (Count == 1) {
+ //
+ // First structure must be $Eeprom$
+ //
+ Test = AsciiStrnCmp (Structure->signature, "$Eeprom$", 8);
+ //
+ // Set CRC32 size
+ //
+ Crc32Size = EepromHeader->crclength;
+ } else if (Count == 2) {
+ //
+ // Second structure must be $EeprMap
+ //
+ Test = AsciiStrnCmp (Structure->signature, "$EeprMap", 8);
+ } else if (Count == 3) {
+ //
+ // Third structure must be $BrdInfo
+ //
+ Test = AsciiStrnCmp (Structure->signature, "$BrdInfo", 8);
+ } else {
+ //
+ // All header signatures begin with $
+ //
+ Test = AsciiStrnCmp (Structure->signature, "$", 0x01);
+ }
+ if (Test != 0) {
+ //
+ // Sanity check failed! Bail.
+ //
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Image is corrupted!\n", __FUNCTION__, __LINE__));
+ Status = EFI_VOLUME_CORRUPTED;
+ goto Exit;
+ }
+ if (AsciiStrnCmp (Structure->signature, "$PromSig", 8) == 0) {
+ //
+ // Check if this is the last structure
+ //
+ Signature = (SIGNATURE_DATA *) Structure;
+ HashSize = Signature->length - sizeof (SIGNATURE_DATA);
+ Hash = ((UINT8 *) Signature) + sizeof (SIGNATURE_DATA);
+ HashType = Signature->hashtype;
+ if (((UINT8 *) Signature - ImageBuffer) + Signature->length + (Structure->length % 0x10) != ImageSize) {
+ //
+ // Oops! $PromSig is not the last structure.
+ //
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: $PromSig structure is not the last structure!\n", __FUNCTION__, __LINE__));
+ Status = EFI_VOLUME_CORRUPTED;
+ goto Exit;
+ }
+ }
+ //
+ // Get next structure on paragraph boundary
+ //
+ Structure = (GENERIC_HEADER *) ((UINT8 *) Structure + Structure->length + (Structure->length % 0x10));
+ }
+ //
+ // Verify CRC32
+ //
+ Crc32 = EepromHeader->crc32;
+ EepromHeader->crc32 = 0;
+ CalculateCrc32 (ImageBuffer, Crc32Size, &EepromHeader->crc32);
+ if (EepromHeader->crc32 != Crc32) {
+ //
+ // Oops!
+ //
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: CRC32 check failed! [%08x:%08x]\n", __FUNCTION__, __LINE__, EepromHeader->crc32, Crc32));
+ Status = EFI_SECURITY_VIOLATION;
+ goto Exit;
+ }
+ //
+ // Verify hash
+ //
+ Status = EFI_SUCCESS;
+ if (HashSize > 0) {
+ //
+ // Check hash
+ //
+ Status = SignedHashCheck (LibraryIndex, ImageBuffer, Crc32Size, Signature);
+ if (EFI_ERROR (Status) && (Status != EFI_MEDIA_CHANGED)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Failed to verify the hash!\n", __FUNCTION__, __LINE__));
+ goto Exit;
+ }
+ }
+
+Exit:
+ //
+ // Free resources
+ //
+ ImageBuffer = EepromFreePool (ImageBuffer);
+ if (EFI_ERROR (Status) && (Status != EFI_MEDIA_CHANGED)) {
+ gImageValidFlag[LibraryIndex] = FALSE;
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - Ending with %r\n", __FUNCTION__, __LINE__, Status));
+ } else {
+ //
+ // Might need to go to a bit flag here to indicate CRC32, hash, and signed hash pass. First round in PEI will only be
+ // able to get CRC32 pass since hash is supported by OpenSSL library and it is HUGE.
+ //
+ gImageValidFlag[LibraryIndex] = TRUE;
+ }
+ return Status;
+}
+
+//
+// Desc: Registers the raw data libraries
+// Variables: None
+// Return: EFI_SUCCESS, anything else will cause an ASSERT
+//
+EFI_STATUS
+EFIAPI
+EepromInitConstructor (VOID)
+{
+ if (mEepromLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Starting...\n", __FUNCTION__, __LINE__));
+ //
+ // Initiliaze CRC32 tables
+ //
+ if (!mCrcInitFlag) InitializeCrc32Table ();
+
+ //
+ // Initiliaze Library valid flags pointer from PCD. This uses the fact that the PCD library currently just passes out
+ // a pointer to it's internal DB. There is no need to update the PCD, since the pointer already points to the internal
+ // PCD copy. If the PCD library changes to include a CRC check of it's data, then we'll have to start using the PcdSetPtr()
+ // function to set the internal PCD value.
+ //
+ gImageValidFlag = PcdGetPtr (PcdEepromLibraryValid);
+
+ return EFI_SUCCESS;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/EepromLib.h b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/EepromLib.h
new file mode 100644
index 0000000000..83871a4ddf
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/EepromLib.h
@@ -0,0 +1,76 @@
+/** @file
+ Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
+
+ 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 _EEPROM_LIB_COMMON_
+#define _EEPROM_LIB_COMMON_
+////
+//// Header files
+////
+#include <Uefi.h>
+
+#include <Guid/EepromVariable.h>
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/EepromDataLib.h>
+#include <Library/EepromLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PrintLib.h>
+
+#include <EepromStruct.h>
+
+
+////
+//// Defines
+////
+#define HASH_SIGNED_FLAG (1 << 15)
+#define HASH_TYPE_MASK 0x00FF
+#define MAX_HASH_TYPE 5
+#define MAX_DIGEST_SIZE SHA512_DIGEST_SIZE
+#define EFI_CERT_TYPE_RSA2048_SIZE 256
+
+////
+//// TypeDefs
+////
+
+////
+//// Structures
+////
+
+////
+//// Functions
+////
+EFI_STATUS
+EFIAPI
+CalculateCrc32 (
+ IN UINT8 *Data,
+ IN UINTN DataSize,
+ IN OUT UINT32 *CrcOut
+ );
+
+EFI_STATUS
+EFIAPI
+EepromLibNemToMemory (VOID);
+
+EFI_STATUS
+EFIAPI
+SignedHashCheck (
+ IN UINT8 LibraryIndex,
+ IN UINT8 *ImageBuffer,
+ IN UINT32 Crc32Size,
+ IN SIGNATURE_DATA *Signature
+ );
+
+#endif // _EEPROM_LIB_COMMON_
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/EepromLib.inf b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/EepromLib.inf
new file mode 100644
index 0000000000..b7ccb920aa
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/EepromLib.inf
@@ -0,0 +1,63 @@
+## @file
+# Library producing EEPROM structure data functionality.
+#
+# Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+# 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 = 0x00010017
+ BASE_NAME = EepromLib
+ FILE_GUID = 20AF98D0-BE4F-44FB-8C60-CA992FA121D1
+ VERSION_STRING = 1.0
+ MODULE_TYPE = BASE
+ LIBRARY_CLASS = EepromLib
+ CONSTRUCTOR = EepromInitConstructor
+
+[Depex]
+ TRUE
+
+[Guids]
+ gEepromVariableGuid
+
+[LibraryClasses]
+ BaseCryptLib
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ EepromDataLib
+ MemoryAllocationLib
+ PcdLib
+ PrintLib
+ UefiRuntimeServicesTableLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ CryptoPkg/CryptoPkg.dec
+ BroxtonPlatformPkg/PlatformPkg.dec
+ BroxtonSiPkg/BroxtonSiPkg.dec
+
+[Pcd]
+ gPlatformModuleTokenSpaceGuid.PcdEepromAutoPriority
+ gPlatformModuleTokenSpaceGuid.PcdEepromAddress
+ gPlatformModuleTokenSpaceGuid.PcdEepromBus
+ gPlatformModuleTokenSpaceGuid.PcdEepromInMemoryFlag
+ gPlatformModuleTokenSpaceGuid.PcdEepromLibraryValid
+ gPlatformModuleTokenSpaceGuid.PcdEepromMemoryPointer
+ gPlatformModuleTokenSpaceGuid.PcdEepromMemorySize
+ gPlatformModuleTokenSpaceGuid.PcdEepromPublicKeyFile
+
+[Sources]
+ EepromLib.c
+ EepromLib.h
+ ValidateHash.c
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/EepromNullLib.inf b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/EepromNullLib.inf
new file mode 100644
index 0000000000..0aa2137e1b
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/EepromNullLib.inf
@@ -0,0 +1,36 @@
+## @file
+# Library producing EEPROM structure data functionality.
+#
+# Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+# 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 = 0x00010017
+ BASE_NAME = EepromNullLib
+ FILE_GUID = E4E838B1-7D70-42C7-A531-9C8EF44FA748
+ VERSION_STRING = 1.0
+ MODULE_TYPE = BASE
+ LIBRARY_CLASS = EepromNullLib
+
+[Depex]
+ TRUE
+
+[LibraryClasses]
+ DebugLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ BroxtonPlatformPkg/PlatformPkg.dec
+
+[Sources]
+ Null/EepromNullLib.c
+ Null/EepromNullLib.h
diff --git a/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/EepromPeiLib.inf b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/EepromPeiLib.inf
new file mode 100644
index 0000000000..0f619fd2f5
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/EepromPeiLib.inf
@@ -0,0 +1,62 @@
+## @file
+# Library producing EEPROM structure data functionality.
+#
+# Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+# 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 = 0x00010017
+ BASE_NAME = EepromPeiLib
+ FILE_GUID = 2B91CA36-CDBC-4A3B-BDE7-404BA69C8C55
+ VERSION_STRING = 1.0
+ MODULE_TYPE = BASE
+ LIBRARY_CLASS = EepromPeiLib
+ CONSTRUCTOR = EepromInitConstructor
+
+[Depex]
+ TRUE
+
+[Guids]
+ gEepromVariableGuid
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ EepromDataLib
+ MemoryAllocationLib
+ PcdLib
+ PeiServicesLib
+ PrintLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ BroxtonPlatformPkg/PlatformPkg.dec
+ BroxtonSiPkg/BroxtonSiPkg.dec
+
+[Pcd]
+ gPlatformModuleTokenSpaceGuid.PcdEepromAutoPriority
+ gPlatformModuleTokenSpaceGuid.PcdEepromAddress
+ gPlatformModuleTokenSpaceGuid.PcdEepromBus
+ gPlatformModuleTokenSpaceGuid.PcdEepromInMemoryFlag
+ gPlatformModuleTokenSpaceGuid.PcdEepromLibraryValid
+ gPlatformModuleTokenSpaceGuid.PcdEepromMemoryPointer
+ gPlatformModuleTokenSpaceGuid.PcdEepromMemorySize
+
+[Ppis]
+ gEfiPeiReadOnlyVariable2PpiGuid ## SOMETIMES_CONSUMES
+
+[Sources]
+ EepromLib.c
+ EepromLib.h
+ Pei/ValidateHashPei.c
diff --git a/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/Null/EepromNullLib.c b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/Null/EepromNullLib.c
new file mode 100644
index 0000000000..612408a0e0
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/Null/EepromNullLib.c
@@ -0,0 +1,82 @@
+/** @file
+ Common EEPROM library instance.
+
+ Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
+
+ 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 "EepromNullLib.h"
+
+EFI_STATUS
+EFIAPI
+EraseEeprom (
+ IN UINT8 LibraryIndex
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+EFIAPI
+GetEepromStructure (
+ IN UINT8 LibraryIndex,
+ IN OUT CHAR8 Signature[EEPROM_SIGNATURE_SIZE],
+ IN OUT UINT8 **Buffer,
+ IN OUT UINT32 *Size
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+UINT32
+EFIAPI
+GetImageSize (
+ IN UINT8 LibraryIndex
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+EFIAPI
+GetNextEepromStructure (
+ IN UINT8 LibraryIndex,
+ IN OUT UINT32 *Index,
+ IN OUT UINT8 **Buffer,
+ IN OUT UINT32 *Size
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+UINT8
+EFIAPI
+GetValidEepromLibrary (
+ IN BOOLEAN CopyToMemory,
+ IN BOOLEAN MemoryInitialized
+ )
+{
+ return EEPROM_NULL;
+}
+
+VOID
+InitializeEepromPcds (VOID)
+{
+}
+
+EFI_STATUS
+EFIAPI
+ValidateEeprom (
+ IN UINT8 LibraryIndex
+ )
+{
+ return EFI_UNSUPPORTED;
+}
diff --git a/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/Null/EepromNullLib.h b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/Null/EepromNullLib.h
new file mode 100644
index 0000000000..3d576202b5
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/Null/EepromNullLib.h
@@ -0,0 +1,26 @@
+/** @file
+ Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
+
+ 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 _EEPROM_NULL_LIB_COMMON_
+#define _EEPROM_NULL_LIB_COMMON_
+////
+//// Header files
+////
+#include <Uefi.h>
+#include <EepromStruct.h>
+
+#include <Library/DebugLib.h>
+#include <Library/EepromDataLib.h>
+#include <Library/EepromLib.h>
+
+#endif // _EEPROM_NULL_LIB_COMMON_
diff --git a/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/Pei/ValidateHashPei.c b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/Pei/ValidateHashPei.c
new file mode 100644
index 0000000000..b039d9885b
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/Pei/ValidateHashPei.c
@@ -0,0 +1,251 @@
+/** @file
+ Common EEPROM library instance.
+
+ Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
+
+ 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 "EepromLib.h"
+
+#include <PiPei.h>
+#include <Library/HobLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Ppi/ReadOnlyVariable2.h>
+
+UINTN
+EFIAPI
+DisplayStackPointer (
+ IN CHAR8 *Function,
+ IN UINTN LineNumber
+ )
+{
+ EFI_HOB_HANDOFF_INFO_TABLE *Hob;
+ UINTN Temp;
+
+ Hob = GetHobList ();
+ Temp = 0;
+ if ((Hob != NULL) & (mEepromDataLibDebugFlag)) {
+ DEBUG ((DEBUG_INFO, "%a (#%4d) - INFO: FreeTop = %08x\n", __FUNCTION__, __LINE__, Hob->EfiFreeMemoryTop));
+ DEBUG ((DEBUG_INFO, "%a (#%4d) - INFO: FreeBottom = %08x\n", __FUNCTION__, __LINE__, Hob->EfiFreeMemoryBottom));
+ Temp = (UINTN) Hob->EfiFreeMemoryBottom;
+ }
+
+ return Temp;
+}
+
+EFI_STATUS
+EFIAPI
+GetEepromVariable (
+ IN UINT8 LibraryIndex,
+ OUT UINT8 **Buffer,
+ OUT UINT32 *BufferSize
+ )
+{
+ UINT32 Attributes;
+ UINT8 *Data;
+ EFI_STATUS Status;
+ CHAR16 VariableName[32];
+ EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariableServices;
+ UINTN VariableSize;
+
+ //
+ // Initialize variables
+ //
+ Attributes = 0;
+ Data = NULL;
+ Status = EFI_SUCCESS;
+ UnicodeSPrint (VariableName, 32, L"PromSig-%d", LibraryIndex);
+
+ //
+ // Sanity checks
+ //
+ if (LibraryIndex >= EEPROM_DATA_LIBRARY_INDEX_MAX) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Library index is larger than %d!\n", __FUNCTION__, __LINE__, EEPROM_DATA_LIBRARY_INDEX_MAX - 1));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ if ((*Buffer != NULL) || (BufferSize == NULL)) {
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+
+ //
+ // Find variable services
+ //
+ Status = PeiServicesLocatePpi (&gEfiPeiReadOnlyVariable2PpiGuid, 0, NULL, (VOID **) &VariableServices);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Failed to locate Variable PPI! [%r]\n", __FUNCTION__, __LINE__, Status));
+ goto Exit;
+ }
+
+ //
+ // Get variable size
+ //
+ VariableSize = 0;
+ Status = VariableServices->GetVariable (
+ VariableServices, // *This
+ VariableName, // Variable name in Unicode
+ &gEepromVariableGuid, // Variable GUID
+ NULL, // Attributes
+ &VariableSize, // Data size
+ NULL // Data
+ );
+ if (Status != EFI_BUFFER_TOO_SMALL) {
+ if (Status == EFI_NOT_FOUND) {
+ //
+ // No variable to find
+ //
+ *Buffer = NULL;
+ *BufferSize = 0;
+ Status = EFI_SUCCESS;
+ goto Exit;
+ } else {
+ //
+ // Oops!
+ //
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Failed to get size of variable! [%r]\n", __FUNCTION__, __LINE__, Status));
+ goto Exit;
+ }
+ }
+
+ //
+ // Allocate buffer
+ //
+ Data = EepromAllocatePool (VariableSize);
+ if (Data == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Failed to allocate buffer! [%r]\n", __FUNCTION__, __LINE__, Status));
+ goto Exit;
+ }
+
+ //
+ // Get variable
+ //
+ Status = VariableServices->GetVariable (
+ VariableServices, // *This
+ VariableName, // Variable name in Unicode
+ &gEepromVariableGuid, // Variable GUID
+ NULL, // Attributes
+ &VariableSize, // Data size
+ Data // Data
+ );
+ if (EFI_ERROR (Status)) {
+ //
+ // Failed to get data
+ //
+ *Buffer = NULL;
+ *BufferSize = 0;
+ } else {
+ *Buffer = Data;
+ *BufferSize = VariableSize;
+ }
+
+Exit:
+ if (EFI_ERROR (Status)) {
+ Data = EepromFreePool (Data);
+ }
+ return Status;
+}
+
+BOOLEAN
+EFIAPI
+InPeiPhase (VOID)
+{
+ return TRUE;
+}
+
+EFI_STATUS
+EFIAPI
+SignedHashCheck (
+ IN UINT8 LibraryIndex,
+ IN UINT8 *ImageBuffer,
+ IN UINT32 Crc32Size,
+ IN SIGNATURE_DATA *Signature
+ )
+{
+ UINT8 *Hash;
+ UINT32 HashSize;
+ EFI_STATUS Status;
+ UINT8 *Variable;
+ UINT32 VariableSize;
+
+ //
+ // Initialize variables
+ //
+ Hash = ((UINT8 *) Signature) + sizeof (SIGNATURE_DATA);
+ HashSize = Signature->length - sizeof (SIGNATURE_DATA);
+ Status = EFI_UNSUPPORTED;
+ Variable = NULL;
+ VariableSize = 0;
+
+ //
+ // Sanity checks
+ //
+ if (LibraryIndex >= EEPROM_DATA_LIBRARY_INDEX_MAX) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Library index is larger than %d!\n", __FUNCTION__, __LINE__, EEPROM_DATA_LIBRARY_INDEX_MAX - 1));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ if (Signature == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Buffer is NULL!\n", __FUNCTION__, __LINE__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ if (Signature->hashtype == 0) {
+ //
+ // Nothing to do. Bail.
+ //
+ Status = EFI_SUCCESS;
+ goto Exit;
+ }
+
+ //
+ // Get stored hash
+ //
+ Status = GetEepromVariable (LibraryIndex, &Variable, &VariableSize);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Failed to get variable! [%r]\n", __FUNCTION__, __LINE__, Status));
+ goto Exit;
+ }
+
+ //
+ // Sanity checks
+ //
+ if (VariableSize == 0) {
+ //
+ // Nothing stored for this library. Bail.
+ //
+ Status = EFI_MEDIA_CHANGED;
+ goto Exit;
+ }
+ if (VariableSize != HashSize) {
+ Status = EFI_MEDIA_CHANGED;
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Stored size doesn't match real size! [%r]\n", __FUNCTION__, __LINE__, Status));
+ goto Exit;
+ }
+
+ //
+ // Compare stored to real
+ //
+ if (CompareMem (Variable, Hash, HashSize) != 0) {
+ //
+ // Failed security match
+ //
+ Status = EFI_SECURITY_VIOLATION;
+ } else {
+ Status = EFI_SUCCESS;
+ }
+
+Exit:
+ Variable = EepromFreePool (Variable);
+ return Status;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/ValidateHash.c b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/ValidateHash.c
new file mode 100644
index 0000000000..355033cbef
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/ValidateHash.c
@@ -0,0 +1,399 @@
+/** @file
+ Common EEPROM library instance.
+
+ Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
+
+ 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 "EepromLib.h"
+
+#include <Library/BaseCryptLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+
+CONST UINT8 mRsaE[] = {0x01, 0x00, 0x01};
+CONST UINT8 mHashSizeLookup[] = {
+ 0x00,
+ MD5_DIGEST_SIZE,
+ SHA1_DIGEST_SIZE,
+ SHA256_DIGEST_SIZE,
+ SHA384_DIGEST_SIZE,
+ SHA512_DIGEST_SIZE
+ };
+
+UINTN
+EFIAPI
+DisplayStackPointer (
+ IN CHAR8 *Function,
+ IN UINTN LineNumber
+ )
+{
+ UINT8 *Temp;
+
+ Temp = AllocatePool (1);
+ if (mEepromDataLibDebugFlag) {
+ DEBUG ((DEBUG_INFO, "%a (#%4d) - INFO: FreeBottom = %08x\n", __FUNCTION__, __LINE__, Temp));
+ }
+
+ return (UINTN) Temp;
+}
+
+BOOLEAN
+EFIAPI
+InPeiPhase (VOID)
+{
+ return FALSE;
+}
+
+EFI_STATUS
+EFIAPI
+SetEepromVariable (
+ IN UINT8 LibraryIndex,
+ IN UINT8 *Buffer,
+ IN UINT32 BufferSize
+ )
+{
+ UINT32 Attributes;
+ EFI_STATUS Status;
+ CHAR16 VariableName[32];
+
+ //
+ // Initialize variables
+ //
+ Attributes = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS;
+ Status = EFI_SUCCESS;
+ UnicodeSPrint (VariableName, 32, L"PromSig-%d", LibraryIndex);
+
+ //
+ // Sanity checks
+ //
+ if (LibraryIndex >= EEPROM_DATA_LIBRARY_INDEX_MAX) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Library index is larger than %d!\n", __FUNCTION__, __LINE__, EEPROM_DATA_LIBRARY_INDEX_MAX - 1));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ if ((Buffer == NULL) && (BufferSize > 0)) {
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+
+ //
+ // Set variable
+ //
+ Status = gRT->SetVariable (
+ VariableName, // Variable name in UniCode
+ &gEepromVariableGuid, // Variable GUID
+ Attributes, // Attributes
+ BufferSize, // Data size
+ Buffer // Data
+ );
+
+Exit:
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+SignedHashCheck (
+ IN UINT8 LibraryIndex,
+ IN UINT8 *ImageBuffer,
+ IN UINT32 Crc32Size,
+ IN SIGNATURE_DATA *Signature
+ )
+{
+ UINT8 Digest[MAX_DIGEST_SIZE];
+ FV_FUNCTION_INFO FvInfo;
+ EFI_GUID FvPublicKeyFile;
+ UINT8 *Hash;
+ UINT32 HashSize;
+ BOOLEAN HashStatus;
+ UINT16 HashType;
+ UINT8 *PublicKey;
+ UINT32 PublicKeySize;
+ VOID *Rsa;
+ BOOLEAN RsaStatus;
+ UINT8 *SignedHash;
+ UINT32 SignedHashSize;
+ EFI_STATUS Status;
+
+ //
+ // Initialize variables
+ //
+ CopyMem (&FvPublicKeyFile, PcdGetPtr (PcdEepromPublicKeyFile), sizeof (EFI_GUID));
+ ZeroMem (&FvInfo, sizeof (FV_FUNCTION_INFO));
+ FvInfo.LibraryIndex = EEPROM_FV;
+ FvInfo.FvFileGuid = &FvPublicKeyFile;
+ Hash = ((UINT8 *) Signature) + sizeof (SIGNATURE_DATA);
+ HashType = Signature->hashtype;
+ HashSize = mHashSizeLookup[HashType & HASH_TYPE_MASK];
+ PublicKey = NULL;
+ PublicKeySize = 0;
+ Rsa = NULL;
+ SignedHash = NULL;
+ SignedHashSize = 0;
+ Status = EFI_UNSUPPORTED;
+ if (HashType & HASH_SIGNED_FLAG) {
+ SignedHash = ((UINT8 *) Signature) + sizeof (SIGNATURE_DATA) + HashSize;
+ SignedHashSize = Signature->length - sizeof (SIGNATURE_DATA) - HashSize;
+ }
+
+ //
+ // Sanity checks
+ //
+ if (LibraryIndex >= EEPROM_DATA_LIBRARY_INDEX_MAX) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Library index is larger than %d!\n", __FUNCTION__, __LINE__, EEPROM_DATA_LIBRARY_INDEX_MAX - 1));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ if ((ImageBuffer == NULL) || (Signature == NULL)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Buffer is NULL!\n", __FUNCTION__, __LINE__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ if (Crc32Size == 0) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Buffer size is 0!\n", __FUNCTION__, __LINE__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ if (HashType == 0) {
+ //
+ // Nothing to do. Bail.
+ //
+ Status = EFI_SUCCESS;
+ goto Exit;
+ }
+ if ((HashType & HASH_TYPE_MASK) > MAX_HASH_TYPE) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: HashType out of bounds! [%04x]\n", __FUNCTION__, __LINE__, HashType));
+ Status = EFI_COMPROMISED_DATA;
+ goto Exit;
+ }
+ if ((Hash == NULL) || (HashSize == 0)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Buffer or buffer size is NULL!\n", __FUNCTION__, __LINE__));
+ Status = EFI_COMPROMISED_DATA;
+ goto Exit;
+ }
+ if ((SignedHashSize != 256) && (SignedHashSize != 0)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: SignedHashSize failed! [%02x]\n", __FUNCTION__, __LINE__, SignedHashSize));
+ Status = EFI_COMPROMISED_DATA;
+ goto Exit;
+ }
+
+ //
+ // Clear existing NvStorage variable if it exists. gEepromVariableGuid:L"PromSig-#"
+ //
+ Status = SetEepromVariable (LibraryIndex, NULL, 0);
+ if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Failed to delete variable PromSig-%d! [%r]\n", __FUNCTION__, __LINE__, LibraryIndex, Status));
+ goto Exit;
+ }
+
+ //
+ // Figure out what hash is being used
+ //
+ switch (HashType & HASH_TYPE_MASK) {
+ case HASH_NONE:
+ //
+ // Nothing to do. Bail.
+ //
+ break;
+ case HASH_MD5:
+ //
+ // MD5 hashing
+ //
+ ZeroMem (Digest, MAX_DIGEST_SIZE);
+ HashStatus = Md5HashAll (ImageBuffer, Crc32Size, Digest);
+ if (!HashStatus) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Image failed MD5 hash check!\n", __FUNCTION__, __LINE__));
+ Status = EFI_SECURITY_VIOLATION;
+ goto Exit;
+ }
+ if (CompareMem (Digest, Hash, MD5_DIGEST_SIZE) != 0) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Image failed MD5 hash check!\n", __FUNCTION__, __LINE__));
+ Status = EFI_SECURITY_VIOLATION;
+ goto Exit;
+ }
+ HashSize = MD5_DIGEST_SIZE;
+ break;
+ case HASH_SHA1:
+ //
+ // SHA1 hashing
+ //
+ ZeroMem (Digest, MAX_DIGEST_SIZE);
+ HashStatus = Sha1HashAll (ImageBuffer, Crc32Size, Digest);
+ if (!HashStatus) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Image failed SHA1 hash check!\n", __FUNCTION__, __LINE__));
+ Status = EFI_SECURITY_VIOLATION;
+ goto Exit;
+ }
+ if (CompareMem (Digest, Hash, SHA1_DIGEST_SIZE) != 0) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Image failed SHA1 hash check!\n", __FUNCTION__, __LINE__));
+ Status = EFI_SECURITY_VIOLATION;
+ goto Exit;
+ }
+ HashSize = SHA1_DIGEST_SIZE;
+ break;
+ case HASH_SHA256:
+ //
+ // SHA256 hashing
+ //
+ ZeroMem (Digest, MAX_DIGEST_SIZE);
+ HashStatus = Sha256HashAll (ImageBuffer, Crc32Size, Digest);
+ if (!HashStatus) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Image failed SHA256 hash check!\n", __FUNCTION__, __LINE__));
+ Status = EFI_SECURITY_VIOLATION;
+ goto Exit;
+ }
+ if (CompareMem (Digest, Hash, SHA256_DIGEST_SIZE) != 0) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Image failed SHA256 hash check!\n", __FUNCTION__, __LINE__));
+ Status = EFI_SECURITY_VIOLATION;
+ goto Exit;
+ }
+ HashSize = SHA256_DIGEST_SIZE;
+ break;
+ case HASH_SHA384:
+ //
+ // SHA384 hashing
+ //
+ ZeroMem (Digest, MAX_DIGEST_SIZE);
+ HashStatus = Sha384HashAll (ImageBuffer, Crc32Size, Digest);
+ if (!HashStatus) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Image failed SHA384 hash check!\n", __FUNCTION__, __LINE__));
+ Status = EFI_SECURITY_VIOLATION;
+ goto Exit;
+ }
+ if (CompareMem (Digest, Hash, SHA384_DIGEST_SIZE) != 0) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Image failed SHA384 hash check!\n", __FUNCTION__, __LINE__));
+ Status = EFI_SECURITY_VIOLATION;
+ goto Exit;
+ }
+ HashSize = SHA384_DIGEST_SIZE;
+ break;
+ case HASH_SHA512:
+ //
+ // SHA512 hashing
+ //
+ ZeroMem (Digest, MAX_DIGEST_SIZE);
+ HashStatus = Sha512HashAll (ImageBuffer, Crc32Size, Digest);
+ if (!HashStatus) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Image failed SHA512 hash check!\n", __FUNCTION__, __LINE__));
+ Status = EFI_SECURITY_VIOLATION;
+ goto Exit;
+ }
+ if (CompareMem (Digest, Hash, SHA512_DIGEST_SIZE) != 0) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Image failed SHA512 hash check!\n", __FUNCTION__, __LINE__));
+ Status = EFI_SECURITY_VIOLATION;
+ goto Exit;
+ }
+ HashSize = SHA512_DIGEST_SIZE;
+ break;
+ default:
+ //
+ // Oops!
+ //
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Unknown hash type [%04x]!\n", __FUNCTION__, __LINE__, HashType));
+ Status = EFI_VOLUME_CORRUPTED;
+ goto Exit;
+ break;
+ }
+
+ //
+ // Does this have a signed hash?
+ //
+ if ((HashType & HASH_SIGNED_FLAG) != HASH_SIGNED_FLAG) {
+ //
+ // Nope. Bail.
+ //
+ Status = EFI_SUCCESS;
+ goto
Exit;
+ }
+
+ //
+ // Get size of public key file in FV
+ //
+ PublicKey = EepromAllocatePool (2);
+ Status = ReadEeprom (EEPROM_FV, 0, &PublicKeySize, PublicKey, &FvInfo);
+ if ((Status != EFI_BUFFER_TOO_SMALL) || (PublicKeySize == 0)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - Finding Public key file size returned with %r and a size of %08x\n", __FUNCTION__, __LINE__, Status, PublicKeySize));
+ Status = EFI_COMPROMISED_DATA;
+ goto Exit;
+ }
+
+ //
+ // Allocate buffer for public key
+ //
+ PublicKey = EepromFreePool (PublicKey);
+ PublicKey = EepromAllocatePool (PublicKeySize);
+ if (PublicKey == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+
+ //
+ // Read in Public key from FV
+ //
+ Status = ReadEeprom (EEPROM_FV, 0, &PublicKeySize, PublicKey, &FvInfo);
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
+
+ //
+ // Verify signature
+ //
+ Rsa = RsaNew ();
+ if (Rsa == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - RsaNew() returned NULL buffer!\n", __FUNCTION__, __LINE__));
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+
+ //
+ // Set RSA Key Components.
+ // NOTE: Only N and E are needed to be set as RSA public key for signature verification.
+ //
+ RsaStatus = RsaSetKey (Rsa, RsaKeyN, PublicKey, EFI_CERT_TYPE_RSA2048_SIZE);
+ if (!RsaStatus) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - RsaSetKey(RsaKeyN) failed!\n", __FUNCTION__, __LINE__));
+ Status = EFI_ABORTED;
+ goto Exit;
+ }
+
+ RsaStatus = RsaSetKey (Rsa, RsaKeyE, mRsaE, sizeof (mRsaE));
+ if (!RsaStatus) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - RsaSetKey(RsaKeyE) failed!\n", __FUNCTION__, __LINE__));
+ Status = EFI_ABORTED;
+ goto Exit;
+ }
+
+ RsaStatus = RsaPkcs1Verify (Rsa, Hash, HashSize, SignedHash, SignedHashSize);
+ if (!RsaStatus) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - RsaPkcs1Verify() failed!\n", __FUNCTION__, __LINE__));
+ Status = EFI_SECURITY_VIOLATION;
+ goto Exit;
+ }
+
+Exit:
+ if (Rsa != NULL) {
+ RsaFree (Rsa);
+ }
+ PublicKey = EepromFreePool (PublicKey);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - Ending with %r\n", __FUNCTION__, __LINE__, Status));
+ } else if (HashType != 0) {
+ //
+ // This is where a copy of the $PromSig data is stored in NvStorage. gEepromVariableGuid:L"PromSig-#"
+ //
+ Status = SetEepromVariable (LibraryIndex, Hash, (HashSize + SignedHashSize));
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Failed to delete variable PromSig-%d! [%r]\n", __FUNCTION__, __LINE__, LibraryIndex, Status));
+ }
+ }
+ return Status;
+}
+
--
2.14.1.windows.1
^ permalink raw reply related [flat|nested] 4+ messages in thread