* [Patch][edk2-platforms/devel-IntelAtomProcessorE3900 1/5] Add EepromApp.
@ 2018-07-23 2:39 zwei4
2018-07-23 2:39 ` [Patch][edk2-platforms/devel-IntelAtomProcessorE3900 3/5] Library producing EEPROM raw data functionality zwei4
` (2 more replies)
0 siblings, 3 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
Add EepromApp which could read, write, verify and dump the EERPOM data.
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/EepromApp/EepromApp.c | 2090 ++++++++++++++++++++
.../Common/Features/Eeprom/EepromApp/EepromApp.h | 196 ++
.../Common/Features/Eeprom/EepromApp/EepromApp.inf | 62 +
3 files changed, 2348 insertions(+)
create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromApp/EepromApp.c
create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromApp/EepromApp.h
create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromApp/EepromApp.inf
diff --git a/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromApp/EepromApp.c b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromApp/EepromApp.c
new file mode 100644
index 0000000000..9e1eb66f54
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromApp/EepromApp.c
@@ -0,0 +1,2090 @@
+/** @file
+
+ This application will read/write/verify/dump the EERPOM data.
+
+ 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 "EepromApp.h"
+
+BOOLEAN gDebugFlag = FALSE;
+
+/**
+ UEFI application entry point which has an interface similar to a
+ standard C main function.
+
+ The ShellCEntryLib library instance wrappers the actual UEFI application
+ entry point and calls this ShellAppMain function.
+
+ @param[in] Argc The number of items in Argv.
+ @param[in] Argv Array of pointers to strings.
+
+ @retval 0 The application exited normally.
+ @retval Other An error occurred.
+
+**/
+INTN
+EFIAPI
+ShellAppMain (
+ IN UINTN Argc,
+ IN CHAR16 **Argv
+ )
+{
+ BOOLEAN InvalidFlag;
+ PROGRAM_INFO ProgramInfo;
+ SHELL_STATUS Status;
+
+ if (gDebugFlag) Print (L"%a(#%d) - Starting...\n", __FUNCTION__, __LINE__);
+
+ // Initialize Variables
+ InvalidFlag = FALSE;
+ Status = SHELL_SUCCESS;
+ ZeroMem (&ProgramInfo, sizeof (ProgramInfo));
+
+
+ // Check for invalid conditions
+ if (Argv == NULL) {
+ if (gDebugFlag) Print (L"ERROR: [#%d] Internal coding error!\n", __LINE__);
+ Status = SHELL_INVALID_PARAMETER;
+ goto Exit;
+ }
+
+ // Parse CLI parameters
+ ParseParameters (Argc, Argv, &ProgramInfo);
+
+ // Print App version
+ Print (L"EepromApp - Version #%s\n", APP_VERSION);
+ Print (L"Copyright (c) %s Intel Corporation. All rights reserved.\n\n", APP_COPYRIGHT);
+
+ // Help requested?
+ if (ProgramInfo.HelpFlag) {
+ PrintHelp ();
+ goto Exit;
+ }
+
+ // Check for invalid states
+ if (CheckForInvalidOptions (&ProgramInfo) != SHELL_SUCCESS) {
+ InvalidFlag = TRUE;
+ Print (L"ERROR: Invalid CLI option(s)!\n");
+ goto Exit;
+ }
+
+ //
+ // Test GetValidEepromLibrary()
+ //
+ if (!ProgramInfo.ScanFlag) {
+ //
+ // Skip this if we are doing a scan.
+ //
+ Print (L"- GetValidEepromLibrary() = %a\n", mEepromLibraryString[GetValidEepromLibrary (TRUE, TRUE)]);
+ } else {
+ // Scanning
+ Status = ScanOption (&ProgramInfo);
+ if (Status != SHELL_SUCCESS) {
+ goto Exit;
+ }
+ }
+
+ // Check?
+ if (ProgramInfo.CheckFlag) {
+ if (ProgramInfo.ReadLibraryIndex > EEPROM_DATA_LIBRARY_INDEX_MAX) {
+ Print (L"ERROR: Library index you want to check is larger than %d!\n", EEPROM_DATA_LIBRARY_INDEX_MAX);
+ Status = SHELL_INVALID_PARAMETER;
+ goto Exit;
+ }
+ Status = CheckOption (&ProgramInfo);
+ } else
+
+ // Dump human?
+ if (ProgramInfo.DumpHumanFlag) {
+ if (ProgramInfo.DumpHumanLibraryIndex > EEPROM_DATA_LIBRARY_INDEX_MAX) {
+ Print (L"ERROR: Library index you want to check is larger than %d!\n", EEPROM_DATA_LIBRARY_INDEX_MAX);
+ Status = SHELL_INVALID_PARAMETER;
+ goto Exit;
+ }
+ Status = DumpHumanOption (&ProgramInfo);
+ } else
+
+ // Dump raw?
+ if (ProgramInfo.DumpRawFlag) {
+ if (ProgramInfo.DumpRawLibraryIndex > EEPROM_DATA_LIBRARY_INDEX_MAX) {
+ Print (L"ERROR: Library index you want to check is larger than %d!\n", EEPROM_DATA_LIBRARY_INDEX_MAX);
+ Status = SHELL_INVALID_PARAMETER;
+ goto Exit;
+ }
+ Status = DumpRawOption (&ProgramInfo);
+ } else
+
+ // Erase?
+ if (ProgramInfo.EraseFlag) {
+ if (ProgramInfo.EraseLibraryIndex > EEPROM_DATA_LIBRARY_INDEX_MAX) {
+ Print (L"ERROR: Library index you want to check is larger than %d!\n", EEPROM_DATA_LIBRARY_INDEX_MAX);
+ Status = SHELL_INVALID_PARAMETER;
+ goto Exit;
+ }
+ Status = EraseOption (&ProgramInfo);
+ } else
+
+ // Read?
+ if (ProgramInfo.ReadFlag) {
+ if (ProgramInfo.ReadLibraryIndex > EEPROM_DATA_LIBRARY_INDEX_MAX) {
+ Print (L"ERROR: Library index you want to read is larger than %d!\n", EEPROM_DATA_LIBRARY_INDEX_MAX);
+ Status = SHELL_INVALID_PARAMETER;
+ goto Exit;
+ }
+ if (ProgramInfo.ReadFileName == NULL) {
+ Print (L"ERROR: Missing the filename!\n");
+ Status = SHELL_INVALID_PARAMETER;
+ goto Exit;
+ }
+ Status = ReadOption (&ProgramInfo);
+ } else
+
+ // Verify?
+ if (ProgramInfo.VerifyFlag) {
+ if (ProgramInfo.VerifyLibraryIndex > EEPROM_DATA_LIBRARY_INDEX_MAX) {
+ Print (L"ERROR: Library index you want to verify is larger than %d!\n", EEPROM_DATA_LIBRARY_INDEX_MAX);
+ Status = SHELL_INVALID_PARAMETER;
+ goto Exit;
+ }
+ if (ProgramInfo.VerifyFileName == NULL) {
+ Print (L"ERROR: Missing the filename!\n");
+ Status = SHELL_INVALID_PARAMETER;
+ goto Exit;
+ }
+ Status = VerifyOption (&ProgramInfo);
+ } else
+
+ // Write?
+ if (ProgramInfo.WriteFlag) {
+ if (ProgramInfo.WriteLibraryIndex > EEPROM_DATA_LIBRARY_INDEX_MAX) {
+ Print (L"ERROR: Library index you want to write is larger than %d!\n", EEPROM_DATA_LIBRARY_INDEX_MAX);
+ Status = SHELL_INVALID_PARAMETER;
+ goto Exit;
+ }
+ if (ProgramInfo.WriteFileName == NULL) {
+ Print (L"ERROR: Missing the filename!\n");
+ Status = SHELL_INVALID_PARAMETER;
+ goto Exit;
+ }
+ Status = WriteOption (&ProgramInfo);
+ } else
+
+ // This is invalid
+ {
+ InvalidFlag = TRUE;
+ Print (L"ERROR: Invalid CLI option(s)!\n");
+ }
+
+Exit:
+ // Invalid?
+ if (InvalidFlag) {
+ Status = SHELL_INVALID_PARAMETER;
+ }
+
+ //
+ // Free resources
+ //
+ if (ProgramInfo.CheckFile != NULL) {
+ FreePool (ProgramInfo.CheckFile);
+ ProgramInfo.CheckFile = NULL;
+ }
+ if (ProgramInfo.DumpHumanFile != NULL) {
+ FreePool (ProgramInfo.DumpHumanFile);
+ ProgramInfo.DumpHumanFile = NULL;
+ }
+ if (ProgramInfo.DumpRawFile != NULL) {
+ FreePool (ProgramInfo.DumpRawFile);
+ ProgramInfo.DumpRawFile = NULL;
+ }
+ if (ProgramInfo.ReadFile != NULL) {
+ FreePool (ProgramInfo.ReadFile);
+ ProgramInfo.ReadFile = NULL;
+ }
+ if (ProgramInfo.VerifyFile != NULL) {
+ FreePool (ProgramInfo.VerifyFile);
+ ProgramInfo.VerifyFile = NULL;
+ }
+ if (ProgramInfo.WriteFile != NULL) {
+ FreePool (ProgramInfo.WriteFile);
+ ProgramInfo.WriteFile = NULL;
+ }
+
+ return Status;
+}
+
+SHELL_STATUS
+BufferToMemory (
+ IN UINT8 *Buffer,
+ IN UINT32 BufferSize,
+ OUT UINT8 **MemoryBuffer,
+ OUT UINT32 *MemoryBufferSize
+ )
+{
+ EFI_STATUS EfiStatus;
+ UINT8 *ImageBuffer;
+ UINT32 ImageSize;
+ SHELL_STATUS Status;
+
+ if (gDebugFlag) Print (L"%a(#%d) - Starting...\n", __FUNCTION__, __LINE__);
+
+ //
+ // Initialize variables
+ //
+ ImageBuffer = NULL;
+ ImageSize = 0;
+ Status = SHELL_SUCCESS;
+
+ //
+ // Sanity checks
+ //
+ if ((Buffer == NULL) || (BufferSize == 0)) {
+ if (gDebugFlag) Print (L"ERROR: [#%d] Internal coding error!\n", __LINE__);
+ Status = SHELL_INVALID_PARAMETER;
+ goto Exit;
+ }
+ if ((MemoryBuffer == NULL) || (MemoryBufferSize == NULL)) {
+ if (gDebugFlag) Print (L"ERROR: [#%d] Internal coding error!\n", __LINE__);
+ Status = SHELL_INVALID_PARAMETER;
+ goto Exit;
+ }
+
+ //
+ // Find out the size of the image
+ //
+ ImageSize = GetImageSize (EEPROM_MEMORY);
+ if (ImageSize > 0) {
+ //
+ // Something there to read
+ //
+ ImageBuffer = AllocateZeroPool (ImageSize);
+ if (ImageBuffer == NULL) {
+ Print (L"ERROR: [#%d] Failed to allocate buffer!\n", __LINE__);
+ Status = SHELL_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+
+ //
+ // Read in the memory image
+ //
+ EfiStatus = ReadEeprom (EEPROM_MEMORY, 0, &ImageSize, ImageBuffer, NULL);
+ if (EFI_ERROR (EfiStatus)) {
+ Print (L"ERROR: [#%d] Failed to read image (%r)!\n", __LINE__, EfiStatus);
+ Status = SHELL_DEVICE_ERROR;
+ goto Exit;
+ }
+ }
+
+ //
+ // Write out file image to memory
+ //
+ EfiStatus = WriteEeprom (EEPROM_MEMORY, 0, &BufferSize, Buffer, NULL);
+ if (EFI_ERROR (EfiStatus)) {
+ Print (L"ERROR: [#%d] Failed to write image (%r)!\n", __LINE__, EfiStatus);
+ Status = SHELL_DEVICE_ERROR;
+ goto Exit;
+ }
+
+ //
+ // Send out info
+ //
+ *MemoryBuffer = ImageBuffer;
+ *MemoryBufferSize = ImageSize;
+
+Exit:
+ if (EFI_ERROR (EfiStatus)) {
+ if (ImageBuffer != NULL) {
+ FreePool (ImageBuffer);
+ ImageBuffer = NULL;
+ }
+ }
+ return Status;
+}
+
+SHELL_STATUS
+CheckForInvalidOptions (
+ IN PROGRAM_INFO *ProgramInfo
+ )
+{
+ BOOLEAN InvalidFlag;
+ SHELL_STATUS Status;
+
+ if (gDebugFlag) Print (L"%a(#%d) - Starting...\n", __FUNCTION__, __LINE__);
+
+ //
+ // Initialize variables
+ //
+ InvalidFlag = FALSE;
+ Status = SHELL_SUCCESS;
+
+ //
+ // Sanity checks
+ //
+ if (ProgramInfo == NULL) {
+ if (gDebugFlag) Print (L"ERROR: [#%d] Internal coding error!\n", __LINE__);
+ Status = SHELL_INVALID_PARAMETER;
+ goto Exit;
+ }
+
+ //
+ // Dump ProgramInfo for debugging
+ //
+ if (gDebugFlag) DumpProgramInfo (ProgramInfo);
+
+ //
+ // Check for invalid options
+ //
+ if ((ProgramInfo->DumpRawFlag || ProgramInfo->DumpHumanFlag) && (ProgramInfo->ReadFlag)) {
+ InvalidFlag = TRUE;
+ Print (L"ERROR: You can't dump and read at the same time!\n");
+ } else
+
+ if ((ProgramInfo->DumpRawFlag || ProgramInfo->DumpHumanFlag) && (ProgramInfo->VerifyFlag)) {
+ InvalidFlag = TRUE;
+ Print (L"ERROR: You can't dump and verify at the same time!\n");
+ } else
+
+ if ((ProgramInfo->DumpRawFlag || ProgramInfo->DumpHumanFlag) && (ProgramInfo->WriteFlag)) {
+ InvalidFlag = TRUE;
+ Print (L"ERROR: You can't dump and write at the same time!\n");
+ } else
+
+ if (ProgramInfo->CheckFlag && ProgramInfo->ReadFlag) {
+ InvalidFlag = TRUE;
+ Print (L"ERROR: You can't check and read at the same time!\n");
+ } else
+
+ if (ProgramInfo->CheckFlag && ProgramInfo->VerifyFlag) {
+ InvalidFlag = TRUE;
+ Print (L"ERROR: You can't check and verify at the same time!\n");
+ } else
+
+ if (ProgramInfo->CheckFlag && ProgramInfo->WriteFlag) {
+ InvalidFlag = TRUE;
+ Print (L"ERROR: You can't check and write at the same time!\n");
+ } else
+
+ if (ProgramInfo->ReadFlag && ProgramInfo->VerifyFlag) {
+ InvalidFlag = TRUE;
+ Print (L"ERROR: You can't read and verify at the same time!\n");
+ } else
+
+ if (ProgramInfo->ReadFlag && ProgramInfo->WriteFlag) {
+ InvalidFlag = TRUE;
+ Print (L"ERROR: You can't read and write at the same time!\n");
+ } else
+
+ if (ProgramInfo->VerifyFlag && ProgramInfo->WriteFlag) {
+ InvalidFlag = TRUE;
+ Print (L"ERROR: You can't verify and write at the same time!\n");
+ } else
+
+ if (ProgramInfo->CheckFlag && (ProgramInfo->CheckLibraryIndex == EEPROM_EEPROM) &&
+ (!(ProgramInfo->BusFlag && ProgramInfo->AddressFlag) && !ProgramInfo->ScanFlag)) {
+ InvalidFlag = TRUE;
+ Print (L"ERROR: You can't check the security of the image in the EEPROM without specifying the EEPROM bus & address!\n");
+ } else
+
+ if (ProgramInfo->ReadFlag && (ProgramInfo->ReadLibraryIndex == EEPROM_EEPROM) &&
+ (!(ProgramInfo->BusFlag && ProgramInfo->AddressFlag) && !ProgramInfo->ScanFlag)) {
+ InvalidFlag = TRUE;
+ Print (L"ERROR: You can't read the image from the EEPROM without specifying the EEPROM bus & address!\n");
+ } else
+
+ if (ProgramInfo->VerifyFlag && (ProgramInfo->VerifyLibraryIndex == EEPROM_EEPROM) &&
+ (!(ProgramInfo->BusFlag && ProgramInfo->AddressFlag) && !ProgramInfo->ScanFlag)) {
+ InvalidFlag = TRUE;
+ Print (L"ERROR: You can't verify the image in the EEPROM without specifying the EEPROM bus & address!\n");
+ } else
+
+ if (ProgramInfo->WriteFlag && (ProgramInfo->VerifyLibraryIndex == EEPROM_EEPROM) &&
+ (!(ProgramInfo->BusFlag && ProgramInfo->AddressFlag) && !ProgramInfo->ScanFlag)) {
+ InvalidFlag = TRUE;
+ Print (L"ERROR: You can't write the image in the EEPROM without specifying the EEPROM bus & address!\n");
+ } else
+
+ if (ProgramInfo->AddressFlag) {
+ if (ProgramInfo->AddressValue > 0x7F) {
+ Print (L"ERROR: I2C slave address is too large!\n");
+ Status = SHELL_INVALID_PARAMETER;
+ goto Exit;
+ }
+ } else
+
+ if (ProgramInfo->BusFlag) {
+ if (ProgramInfo->BusValue > 7) {
+ Print (L"ERROR: I2C bus number is too large!\n");
+ Status = SHELL_INVALID_PARAMETER;
+ goto Exit;
+ }
+ }
+
+ //
+ // Set return value
+ //
+ if (InvalidFlag) {
+ Status = SHELL_INVALID_PARAMETER;
+ }
+
+Exit:
+ return Status;
+}
+
+SHELL_STATUS
+CheckOption (
+ IN PROGRAM_INFO *ProgramInfo
+ )
+{
+ EFI_STATUS EfiStatus;
+ UINT8 *ImageBuffer;
+ UINT32 ImageSize;
+ SHELL_STATUS Status;
+
+ if (gDebugFlag) Print (L"%a(#%d) - Starting...\n", __FUNCTION__, __LINE__);
+
+ //
+ // Initialize variables
+ //
+ ImageBuffer = NULL;
+ Status = SHELL_SUCCESS;
+
+ //
+ // Sanity checks
+ //
+ if (ProgramInfo == NULL) {
+ if (gDebugFlag) Print (L"ERROR: [#%d] Internal coding error!\n", __LINE__);
+ Status = SHELL_INVALID_PARAMETER;
+ goto Exit;
+ }
+ if (ProgramInfo->CheckFileName != NULL) {
+ if ((ProgramInfo->CheckFile == NULL) || (ProgramInfo->CheckFileSize == 0)) {
+ if (gDebugFlag) Print (L"ERROR: [#%d] Image file is empty!\n", __LINE__);
+ Status = SHELL_INVALID_PARAMETER;
+ goto Exit;
+ }
+ }
+
+ //
+ // Checking security of file image
+ //
+ Print (L" - Validating...\n");
+ if (ProgramInfo->CheckFileName != NULL) {
+ //
+ // Swap File buffer with EEPROM_MEMORY
+ //
+ Status = BufferToMemory (ProgramInfo->CheckFile, ProgramInfo->CheckFileSize, &ImageBuffer, &ImageSize);
+ if (Status != SHELL_SUCCESS) {
+ Print (L"ERROR: [#%d] Failed to retrieve original memory image (%r)!\n", __LINE__, Status);
+ Status = SHELL_DEVICE_ERROR;
+ goto Exit;
+ }
+
+ //
+ // Validate image
+ //
+ EfiStatus = ValidateEeprom (EEPROM_MEMORY);
+ Print (L" - File validation status = %r\n", EfiStatus);
+
+ //
+ // Was there something in memory before?
+ //
+ if (ImageBuffer != NULL) {
+ //
+ // Restore memory image
+ //
+ EfiStatus = WriteEeprom (EEPROM_MEMORY, 0, &ImageSize, ImageBuffer, NULL);
+ if (EFI_ERROR (EfiStatus)) {
+ Print (L"ERROR: [#%d] Failed to restore original memory image (%r)!\n", __LINE__, EfiStatus);
+ Status = SHELL_DEVICE_ERROR;
+ goto Exit;
+ }
+
+ //
+ // Revalidate the memory image
+ //
+ EfiStatus = ValidateEeprom (EEPROM_MEMORY);
+ if (EFI_ERROR (EfiStatus)) {
+ Print (L"ERROR: [#%d] Failed to validate original memory image (%r)!\n", __LINE__, EfiStatus);
+ Status = SHELL_DEVICE_ERROR;
+ goto Exit;
+ }
+ }
+ } else
+
+ //
+ // Just validate the current image
+ //
+ {
+ EfiStatus = ValidateEeprom (ProgramInfo->CheckLibraryIndex);
+ Print (L" - Image validation status = %r\n", EfiStatus);
+ }
+
+ Status = SHELL_SUCCESS;
+
+Exit:
+ //
+ // Free resources
+ //
+ if (ImageBuffer != NULL) {
+ FreePool (ImageBuffer);
+ ImageBuffer = NULL;
+ }
+ return Status;
+}
+
+SHELL_STATUS
+DumpHumanOption (
+ IN PROGRAM_INFO *ProgramInfo
+ )
+{
+ CHAR8 AsciiData[16];
+ VOID *Buffer;
+ UINT32 BufferSize;
+ UINT32 count;
+ EEPROM_FUNCTION_INFO EepromInfo;
+ EFI_STATUS EfiStatus;
+ VOID *FunctionInfo;
+ GENERIC_HEADER *GenericHeader;
+ UINT8 *Hash;
+ UINT32 HashSize;
+ UINT8 *ImageBuffer;
+ UINT32 ImageSize;
+ UINT32 index;
+ UINT8 LibraryIndex;
+ UINT8 *Ptr;
+ UINT8 *Signature;
+ UINT32 SignatureSize;
+ SHELL_STATUS Status;
+ UINT32 StructureSize;
+
+ if (gDebugFlag) Print (L"%a(#%d) - Starting...\n", __FUNCTION__, __LINE__);
+
+ //
+ // Initialize variables
+ //
+ ZeroMem (&EepromInfo, sizeof (EEPROM_FUNCTION_INFO));
+ EepromInfo.Bus = ProgramInfo->BusValue;
+ EepromInfo.Address = ProgramInfo->AddressValue;
+ EepromInfo.LibraryIndex = EEPROM_EEPROM;
+ Buffer = NULL;
+ FunctionInfo = NULL;
+ Hash = NULL;
+ HashSize = 0;
+ ImageBuffer = NULL;
+ LibraryIndex = ProgramInfo->DumpHumanLibraryIndex;
+ Signature = NULL;
+ SignatureSize = 0;
+ Status = SHELL_SUCCESS;
+
+ //
+ // Sanity checks
+ //
+ if (ProgramInfo == NULL) {
+ if (gDebugFlag) Print (L"ERROR: [#%d] Internal coding error!\n", __LINE__);
+ Status = SHELL_INVALID_PARAMETER;
+ goto Exit;
+ }
+ if (ProgramInfo->DumpHumanFileName != NULL) {
+ if ((ProgramInfo->DumpHumanFile == NULL) || (ProgramInfo->DumpHumanFileSize == 0)) {
+ if (gDebugFlag) Print (L"ERROR: [#%d] Image file is empty!\n", __LINE__);
+ Status = SHELL_INVALID_PARAMETER;
+ goto Exit;
+ }
+ }
+
+ if (ProgramInfo->DumpHumanFileName != NULL) {
+ //
+ // Swap File buffer with EEPROM_MEMORY
+ //
+ Status = BufferToMemory (ProgramInfo->DumpHumanFile, ProgramInfo->DumpHumanFileSize, &ImageBuffer, &ImageSize);
+ if (Status != SHELL_SUCCESS) {
+ Print (L"ERROR: [#%d] Failed to retrieve original memory image (%r)!\n", __LINE__, Status);
+ Status = SHELL_DEVICE_ERROR;
+ goto Exit;
+ }
+
+ //
+ // Point to EEPROM_MEMORY library
+ //
+ LibraryIndex = EEPROM_MEMORY;
+ }
+
+ //
+ // Parse the image into human readable form
+ //
+ index = 0;
+ EfiStatus = EFI_SUCCESS;
+ while (!EFI_ERROR (EfiStatus)) {
+ EfiStatus = GetNextEepromStructure (LibraryIndex, &index, (UINT8 **) &Buffer, &BufferSize);
+ if (!EFI_ERROR (EfiStatus)) {
+ //
+ // Got a structure
+ //
+ GenericHeader = (GENERIC_HEADER *) Buffer;
+ CopyMem (AsciiData, GenericHeader->signature, sizeof (GenericHeader->signature));
+ AsciiData[sizeof (GenericHeader->signature)] = 0;
+ StructureSize = GenericHeader->length;
+ if (GenericHeader->signature[0] != '$') {
+ Print (L"ERROR: [#%d] Structure signature [%a] doesn't start with $!\n", __LINE__, AsciiData);
+ EfiStatus = EFI_COMPROMISED_DATA;
+ continue;
+ }
+ //
+ // Dump generic header info
+ //
+ Print (L"Signature = %a\n", AsciiData);
+ Print (L"Major version = %04x\n", GenericHeader->vermajor);
+ Print (L"Minor version = %04x\n", GenericHeader->verminor);
+ Print (L"Length = %08x\n", StructureSize);
+ //
+ // Check for $AcpiTbl
+ //
+ if (AsciiStrnCmp (GenericHeader->signature, "$AcpiTbl", 8) == 0) {
+ ACPI_TABLE *AcpiTable;
+ AcpiTable = (ACPI_TABLE *) Buffer;
+ Ptr = (UINT8 *) Buffer + sizeof (ACPI_TABLE);
+ if (ProgramInfo->VerboseFlag) DumpParagraph (Ptr, (AcpiTable->length - (Ptr - (UINT8 *) Buffer)));
+ } else
+ //
+ // Check for $BrdInfo
+ //
+ if (AsciiStrnCmp (GenericHeader->signature, "$BrdInfo", 8) == 0) {
+ BOARD_INFO_TABLE *BoardInfo;
+ BoardInfo = (BOARD_INFO_TABLE *) Buffer;
+ ZeroMem (AsciiData, 17);
+ CopyMem (AsciiData, BoardInfo->manuname, 16);
+ Print (L"Manufacturing name = %a\n", AsciiData);
+ ZeroMem (AsciiData, 17);
+ CopyMem (AsciiData, BoardInfo->brdname, 16);
+ Print (L"Board name = %a\n", AsciiData);
+ ZeroMem (AsciiData, 17);
+ CopyMem (AsciiData, BoardInfo->brdserial, 16);
+ Print (L"Board serial # = %a\n", AsciiData);
+ Print (L"Board ID = %08x\n", BoardInfo->boardid);
+ Print (L"Fab ID = %08x\n", BoardInfo->fabid);
+ Print (L"EC ID = %08x\n", BoardInfo->ecid);
+ Print (L"Board type = ");
+ if (BoardInfo->boardtype == 0) {
+ Print (L"Main board (RedBox)\n");
+ } else
+ if (BoardInfo->boardtype == 1) {
+ Print (L"Plug-in board\n");
+ } else
+ {
+ Print (L"[%02x] - Unknown\n", BoardInfo->boardtype);
+ }
+ } else
+ //
+ // Check for $EeprMap
+ //
+ if (AsciiStrnCmp (GenericHeader->signature, "$EeprMap", 8) == 0) {
+ EEPROM_MAP *EepromMap;
+ EEPROM_MAP_RECORD *MapRecord;
+ EepromMap = (EEPROM_MAP *) Buffer;
+ MapRecord = (EEPROM_MAP_RECORD *) ((UINT8 *) Buffer + sizeof (EEPROM_MAP));
+ ZeroMem (AsciiData, 17);
+ CopyMem (AsciiData, EepromMap->partlabel, 16);
+ Print (L"Part label = %a\n", AsciiData);
+ Print (L"Block length = %08x\n", EepromMap->blklength);
+ Print (L"Page size = %04x\n", EepromMap->pagesize);
+ Print (L"Total part size = %08x\n", EepromMap->partsize);
+ Print (L"I2C bus number = %02x\n", EepromMap->busnumber);
+ Print (L"Map master = ");
+ if (EepromMap->master == 0) {
+ Print (L"Not the master map\n");
+ } else
+ if (EepromMap->master == 1) {
+ Print (L"Master map\n");
+ } else
+ {
+ Print (L"[%02x] - Unknown\n", EepromMap->master);
+ }
+ Print (L"I2C speed = ");
+ if (EepromMap->speed == 1) {
+ Print (L"100KHz (Standard speed)\n");
+ } else
+ if (EepromMap->speed == 2) {
+ Print (L"400KHz (Fast speed)\n");
+ } else
+ if (EepromMap->speed == 3) {
+ Print (L"3.4MHz (High speed)\n");
+ } else
+ {
+ Print (L"[%02x] - Unknown\n", EepromMap->speed);
+ }
+ //
+ // Loop thru map records
+ //
+ while ((UINT8 *) MapRecord < ((UINT8 *) Buffer + EepromMap->length)) {
+ ZeroMem (AsciiData, 17);
+ CopyMem (AsciiData, MapRecord->maplabel, 16);
+ Print (L" - Record label = %a\n", AsciiData);
+ Print (L" - Record length = %08x\n", MapRecord->length);
+ Print (L" - Binary offset = %08x\n", MapRecord->offset);
+ Print (L" - I2C address = %02x\n", MapRecord->address);
+ //
+ // Increment record
+ //
+ MapRecord++;
+ }
+ } else
+ //
+ // Check for $Eeprom$ structure
+ //
+ if (AsciiStrnCmp (GenericHeader->signature, "$Eeprom$", 8) == 0) {
+ EEPROM_HEADER *EepromHeader;
+ EepromHeader = (EEPROM_HEADER *) Buffer;
+ Print (L"Image length = %08x\n", EepromHeader->structlength);
+ Print (L"Image CRC32 = %08x\n", EepromHeader->crc32);
+ Print (L"Image CRC32 length = %08x\n", EepromHeader->crclength);
+ Print (L"Image version = %08x\n", EepromHeader->version);
+ } else
+ //
+ // Check for $GpioDat
+ //
+ if (AsciiStrnCmp (GenericHeader->signature, "$GpioDat", 8) == 0) {
+ GPIO_DATA_HEADER *GpioHeader;
+ GPIO_DATA_RECORD *GpioRecord;
+ GpioHeader = (GPIO_DATA_HEADER *) Buffer;
+ GpioRecord = (GPIO_DATA_RECORD *) ((UINT8 *) Buffer + sizeof (GPIO_DATA_HEADER));
+ //
+ // Loop thru GPIO records
+ //
+ while ((UINT8 *) GpioRecord < ((UINT8 *) Buffer + GpioHeader->length)) {
+ ZeroMem (AsciiData, 17);
+ CopyMem (AsciiData, GpioRecord->gpiolabel, 16);
+ Print (L" - GPIO label = %a\n", AsciiData);
+ Print (L" - Record length = %08x\n", GpioRecord->length);
+ Print (L" - GPIO offset = %08x\n", GpioRecord->offset);
+ Print (L" - GPIO AND data = %08x\n", GpioRecord->anddata);
+ Print (L" - GPIO OR data = %08x\n", GpioRecord->ordata);
+ Print (L" - GPIO data size = %08x\n", GpioRecord->datasize);
+ Print (L" - GPIO data type = ");
+ if (GpioRecord->datasize == 0) {
+ Print (L"IO\n");
+ } else
+ if (GpioRecord->datasize == 1) {
+ Print (L"MMIO\n");
+ } else
+ if (GpioRecord->datasize == 2) {
+ Print (L"PCI\n");
+ } else
+ if (GpioRecord->datasize == 3) {
+ Print (L"PCIe\n");
+ } else
+ if (GpioRecord->datasize == 4) {
+ Print (L"PAD offset\n");
+ } else
+ {
+ Print (L"[%02x] - Unknown\n", GpioRecord->datasize);
+ }
+ //
+ // Increment record
+ //
+ GpioRecord++;
+ }
+ } else
+ //
+ // Check for $HdCodec
+ //
+ if (AsciiStrnCmp (GenericHeader->signature, "$HdCodec", 8) == 0) {
+ HDA_CODEC *HdaCodec;
+ HdaCodec = (HDA_CODEC *) Buffer;
+ Ptr = (UINT8 *) Buffer + sizeof (HDA_CODEC);
+ if (ProgramInfo->VerboseFlag) DumpParagraph (Ptr, (HdaCodec->length - (Ptr - (UINT8 *) Buffer)));
+ } else
+ //
+ // Check for $Logo$
+ //
+ if (AsciiStrnCmp (GenericHeader->signature, "$Logo$", 6) == 0) {
+ LOGO_DATA *LogoData;
+ LogoData = (LOGO_DATA *) Buffer;
+ Ptr = (UINT8 *) Buffer + sizeof (LOGO_DATA);
+ if (ProgramInfo->VerboseFlag) DumpParagraph (Ptr, (LogoData->length - (Ptr - (UINT8 *) Buffer)));
+ } else
+ //
+ // Check for $MacInfo
+ //
+ if (AsciiStrnCmp (GenericHeader->signature, "$MacInfo", 8) == 0) {
+ NIC_INFO *NicInfo;
+ NicInfo = (NIC_INFO *) Buffer;
+ ZeroMem (AsciiData, 9);
+ CopyMem (AsciiData, NicInfo->nicid, 8);
+ Print (L"NIC ID = %a\n", AsciiData);
+ Print (L"MAC address = %12x\n", NicInfo->macaddr);
+ Print (L"NIC number = %2x\n", NicInfo->nicnum);
+ Ptr = (UINT8 *) Buffer + sizeof (NIC_INFO);
+ if (ProgramInfo->VerboseFlag) DumpParagraph (Ptr, (NicInfo->length - (Ptr - (UINT8 *) Buffer)));
+ } else
+ //
+ // Check for $MemCnfg
+ //
+ if (AsciiStrnCmp (GenericHeader->signature, "$MemCnfg", 8) == 0) {
+ UINT8 Slot;
+ MEMORY_SPD *MemoryData;
+ MemoryData = (MEMORY_SPD *) Buffer;
+ Print (L"SPD slot flags = %04x\n", MemoryData->spdslot);
+ for (Slot = 0; Slot < 16; Slot++) {
+ if (MemoryData->spdslot & (1 << Slot)) {
+ Print (L" - Slot %d support.\n", Slot + 1);
+ }
+ }
+ Ptr = (UINT8 *) Buffer + sizeof (MEMORY_SPD);
+ if (ProgramInfo->VerboseFlag) DumpParagraph (Ptr, (MemoryData->length - (Ptr - (UINT8 *) Buffer)));
+ } else
+ //
+ // Check for $PromSig
+ //
+ if (AsciiStrnCmp (GenericHeader->signature, "$PromSig", 8) == 0) {
+ UINT16 HashType;
+ SIGNATURE_DATA *SignatureData;
+ SignatureData = (SIGNATURE_DATA *) Buffer;
+ Hash = (UINT8 *) Buffer + sizeof (SIGNATURE_DATA);
+ HashType = (SignatureData->hashtype & 0x7FFF);
+ Print (L"Hash type = ");
+ if (HashType == HASH_NONE) {
+ Print (L"None\n");
+ HashSize = 0;
+ } else
+ if (HashType == HASH_MD5) {
+ Print (L"MD5\n");
+ HashSize = MD5DigestSize;
+ } else
+ if (HashType == HASH_SHA1) {
+ Print (L"SHA1\n");
+ HashSize = SHA1DigestSize;
+ } else
+ if (HashType == HASH_SHA256) {
+ Print (L"SHA256\n");
+ HashSize = SHA256DigestSize;
+ } else
+ if (HashType == HASH_SHA384) {
+ Print (L"SHA384\n");
+ HashSize = SHA384DigestSize;
+ } else
+ if (HashType == HASH_SHA512) {
+ Print (L"SHA512\n");
+ HashSize = SHA512DigestSize;
+ } else
+ {
+ Print (L"[%04x] Unknown\n", HashType);
+ }
+ Print (L"Hash signed = ");
+ if (HashType != SignatureData->hashtype) {
+ Print (L"True\n");
+ Signature = Hash + HashSize;
+ SignatureSize = 256;
+ } else {
+ Print (L"False\n");
+ Signature = NULL;
+ SignatureSize = 0;
+ }
+ // Dump hash
+ Print (L"Hash = ");
+ for (count = 0; count < HashSize; count++) {
+ if (((count % 0x10) == 0) && (count > 0)) {
+ Print (L"\n ");
+ }
+ Print (L"%02X", Hash[count]);
+ }
+ Print (L"\n");
+ // Dump signed hash
+ if (HashType != SignatureData->hashtype) {
+ Print (L"Signed Hash = ");
+ for (count = 0; count < SignatureSize; count++) {
+ if (((count % 0x10) == 0) && (count > 0)) {
+ Print (L"\n ");
+ }
+ Print (L"%02X", Signature[count]);
+ }
+ Print (L"\n");
+ }
+ } else
+ //
+ // Check for $uCode$
+ //
+ if (AsciiStrnCmp (GenericHeader->signature, "$uCode$", 7) == 0) {
+ MICROCODE *MicrocodeData;
+ MicrocodeData = (MICROCODE *) Buffer;
+ Ptr = (UINT8 *) Buffer + sizeof (MICROCODE);
+ if (ProgramInfo->VerboseFlag) DumpParagraph (Ptr, (MicrocodeData->length - (Ptr - (UINT8 *) Buffer)));
+ } else
+ //
+ // Check for $Video$
+ //
+ if (AsciiStrnCmp (GenericHeader->signature, "$Video$", 7) == 0) {
+ VIDEO_DATA *VideoData;
+ VideoData = (VIDEO_DATA *) Buffer;
+ Ptr = (UINT8 *) Buffer + sizeof (VIDEO_DATA);
+ if (ProgramInfo->VerboseFlag) DumpParagraph (Ptr, (VideoData->length - (Ptr - (UINT8 *) Buffer)));
+ } else
+ //
+ // Unknown structure
+ //
+ {
+ Ptr = (UINT8 *) Buffer + sizeof (GENERIC_HEADER);
+ if (ProgramInfo->VerboseFlag) DumpParagraph (Ptr, (GenericHeader->length - (Ptr - (UINT8 *) Buffer)));
+ }
+ }
+ Print (L"\n");
+ }
+
+ if (ProgramInfo->CheckFileName != NULL) {
+ //
+ // Restore EEPROM_MEMORY from temp buffer
+ //
+ if (ImageBuffer != NULL) {
+ //
+ // Restore memory image
+ //
+ EfiStatus = WriteEeprom (EEPROM_MEMORY, 0, &ImageSize, ImageBuffer, NULL);
+ if (EFI_ERROR (EfiStatus)) {
+ Print (L"ERROR: [#%d] Failed to restore original memory image (%r)!\n", __LINE__, EfiStatus);
+ Status = SHELL_DEVICE_ERROR;
+ goto Exit;
+ }
+
+ //
+ // Re-validate the memory image
+ //
+ EfiStatus = ValidateEeprom (EEPROM_MEMORY);
+ if (EFI_ERROR (EfiStatus)) {
+ Print (L"ERROR: [#%d] Failed to validate original memory image (%r)!\n", __LINE__, EfiStatus);
+ Status = SHELL_DEVICE_ERROR;
+ goto Exit;
+ }
+ }
+ }
+
+Exit:
+ //
+ // Free resources
+ //
+ if (Buffer != NULL) {
+ FreePool (Buffer);
+ Buffer = NULL;
+ }
+ if (ImageBuffer != NULL) {
+ FreePool (ImageBuffer);
+ ImageBuffer = NULL;
+ }
+ return Status;
+}
+
+VOID
+DumpParagraph (
+ IN VOID *Ptr,
+ IN UINTN Count
+ )
+{
+ CHAR8 AsciiBuffer[17];
+ UINT8 *Data;
+ UINTN Index;
+ UINTN Paragraphs;
+ UINTN PlaceHolder;
+ UINT8 PlaceHolders;
+
+ if (gDebugFlag) Print (L"%a(#%d) - Starting...\n", __FUNCTION__, __LINE__);
+
+ // Check for invalid conditions
+ if (Ptr == NULL) {
+ if (gDebugFlag) Print (L"ERROR: [#%d] Internal coding error!\n", __LINE__);
+ goto Exit;
+ }
+
+ // Start dumping the buffer
+ if (Count > 0 ) {
+ // Initialize variables
+ Data = (UINT8 *) Ptr;
+ Paragraphs = Count / 16;
+ if ((Paragraphs * 16) < Count) {
+ Paragraphs++;
+ }
+ PlaceHolder = Paragraphs;
+ PlaceHolders = 0;
+ while (PlaceHolder > 0) {
+ PlaceHolders++;
+ PlaceHolder >>= 4;
+ }
+
+ // Print Header
+ PrintChar (PlaceHolders + 5, L" ");
+ Print (DIVIDING_LINE);
+ PrintChar (PlaceHolders + 5, L" ");
+ Print (L"| x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF | String |\n");
+ Print (L" +");
+ PrintChar (PlaceHolders + 3, L"-");
+ Print (DIVIDING_LINE);
+
+ // Print data
+ for (Index = 0; Index < (Paragraphs * 16); Index++) {
+ if (Index % 0x10 == 0x00) {
+ if ((Index > 0) && ((Index / 0x10) % 0x04 == 0x00) && (Paragraphs > 6)) {
+ Print (L" +");
+ PrintChar (PlaceHolders + 3, L"-");
+ Print (DIVIDING_LINE);
+ }
+ Print (L" | %0*xx | ", PlaceHolders, (Index / 0x10));
+ }
+
+ // Print the data or a filler
+ if (Index < Count) {
+ Print (L"%02x ", Data[Index]);
+ if ((Data[Index] < 32) || (Data[Index] > 126)) {
+ // Not printable
+ AsciiBuffer[(Index % 0x10)] = '.';
+ } else {
+ // Printable
+ AsciiBuffer[(Index % 0x10)] = Data[Index];
+ }
+ } else {
+ Print (L" ");
+ AsciiBuffer[(Index % 0x10)] = ' ';
+ }
+
+ // Print break or line end if needed
+ if (Index % 0x10 == 0x0F) {
+ AsciiBuffer[16] = 0x00;
+ Print (L"| %a |\n", AsciiBuffer);
+ } else if (Index % 0x04 == 0x03) {
+ Print (L" ");
+ }
+ }
+
+ // Print footer
+ Print (L" +");
+ PrintChar (PlaceHolders + 3, L"-");
+ Print (DIVIDING_LINE);
+ }
+
+Exit:
+ return;
+}
+
+VOID
+DumpProgramInfo (
+ IN PROGRAM_INFO *ProgramInfo
+ )
+{
+ if (gDebugFlag) Print (L"%a(#%d) - Starting...\n", __FUNCTION__, __LINE__);
+
+ Print (L"ProgramInfo @ %08x\n", ProgramInfo);
+ Print (L" - HelpFlag = %02x\n", ProgramInfo->HelpFlag);
+ Print (L" - AddressFlag = %02x\n", ProgramInfo->AddressFlag);
+ Print (L" - AddressValue = %02x\n", ProgramInfo->AddressValue);
+ Print (L" - BusFlag = %02x\n", ProgramInfo->BusFlag);
+ Print (L" - BusValue = %02x\n", ProgramInfo->BusValue);
+ Print (L" - CheckFlag = %02x\n", ProgramInfo->CheckFlag);
+ Print (L" - CheckLibraryIndex = %02x\n", ProgramInfo->CheckLibraryIndex);
+ Print (L" - CheckFile = %08x\n", ProgramInfo->CheckFile);
+ Print (L" - CheckFileName = %s\n", ProgramInfo->CheckFileName);
+ Print (L" - CheckFileSize = %08x\n", ProgramInfo->CheckFileSize);
+ Print (L" - DumpHumanFlag = %02x\n", ProgramInfo->DumpHumanFlag);
+ Print (L" - DumpHumanLibraryIndex = %02x\n", ProgramInfo->DumpHumanLibraryIndex);
+ Print (L" - DumpHumanFile = %08x\n", ProgramInfo->DumpHumanFile);
+ Print (L" - DumpHumanFileName = %s\n", ProgramInfo->DumpHumanFileName);
+ Print (L" - DumpHumanFileSize = %08x\n", ProgramInfo->DumpHumanFileSize);
+ Print (L" - DumpRawFlag = %02x\n", ProgramInfo->DumpRawFlag);
+ Print (L" - DumpRawLibraryIndex = %02x\n", ProgramInfo->DumpRawLibraryIndex);
+ Print (L" - DumpRawFile = %08x\n", ProgramInfo->DumpRawFile);
+ Print (L" - DumpRawFileName = %s\n", ProgramInfo->DumpRawFileName);
+ Print (L" - DumpRawFileSize = %08x\n", ProgramInfo->DumpRawFileSize);
+ Print (L" - EraseFlag = %02x\n", ProgramInfo->EraseFlag);
+ Print (L" - EraseLibraryIndex = %02x\n", ProgramInfo->EraseLibraryIndex);
+ Print (L" - ReadFlag = %02x\n", ProgramInfo->ReadFlag);
+ Print (L" - ReadLibraryIndex = %02x\n", ProgramInfo->ReadLibraryIndex);
+ Print (L" - ReadFile = %08x\n", ProgramInfo->ReadFile);
+ Print (L" - ReadFileName = %s\n", ProgramInfo->ReadFileName);
+ Print (L" - ReadFileSize = %08x\n", ProgramInfo->ReadFileSize);
+ Print (L" - ScanFlag = %02x\n", ProgramInfo->ScanFlag);
+ Print (L" - VerifyFlag = %02x\n", ProgramInfo->VerifyFlag);
+ Print (L" - VerifyLibraryIndex = %02x\n", ProgramInfo->VerifyLibraryIndex);
+ Print (L" - VerifyFile = %08x\n", ProgramInfo->VerifyFile);
+ Print (L" - VerifyFileName = %s\n", ProgramInfo->VerifyFileName);
+ Print (L" - VerifyFileSize = %08x\n", ProgramInfo->VerifyFileSize);
+ Print (L" - WriteFlag = %02x\n", ProgramInfo->WriteFlag);
+ Print (L" - WriteLibraryIndex = %02x\n", ProgramInfo->WriteLibraryIndex);
+ Print (L" - WriteFile = %08x\n", ProgramInfo->WriteFile);
+ Print (L" - WriteFileName = %s\n", ProgramInfo->WriteFileName);
+ Print (L" - WriteFileSize = %08x\n", ProgramInfo->WriteFileSize);
+}
+
+SHELL_STATUS
+DumpRawOption (
+ IN PROGRAM_INFO *ProgramInfo
+ )
+{
+ EEPROM_FUNCTION_INFO EepromInfo;
+ EFI_STATUS EfiStatus;
+ VOID *FunctionInfo;
+ SHELL_STATUS Status;
+
+ if (gDebugFlag) Print (L"%a(#%d) - Starting...\n", __FUNCTION__, __LINE__);
+
+ //
+ // Initialize variables
+ //
+ ZeroMem (&EepromInfo, sizeof (EEPROM_FUNCTION_INFO));
+ EepromInfo.Bus = ProgramInfo->BusValue;
+ EepromInfo.Address = ProgramInfo->AddressValue;
+ EepromInfo.LibraryIndex = EEPROM_EEPROM;
+ FunctionInfo = NULL;
+ Status = SHELL_SUCCESS;
+
+ //
+ // Sanity checks
+ //
+ if (ProgramInfo == NULL) {
+ if (gDebugFlag) Print (L"ERROR: [#%d] Internal coding error!\n", __LINE__);
+ Status = SHELL_INVALID_PARAMETER;
+ goto Exit;
+ }
+ if (ProgramInfo->DumpRawFileName != NULL) {
+ if ((ProgramInfo->DumpRawFile == NULL) || (ProgramInfo->DumpRawFileSize == 0)) {
+ if (gDebugFlag) Print (L"ERROR: [#%d] Image file is empty!\n", __LINE__);
+ Status = SHELL_INVALID_PARAMETER;
+ goto Exit;
+ }
+ }
+
+ //
+ // Read in the image file
+ //
+ if (ProgramInfo->DumpRawFileName == NULL) {
+ //
+ // Find out the size of the image
+ //
+ ProgramInfo->DumpRawFileSize = GetImageSize (ProgramInfo->DumpRawLibraryIndex);
+ ProgramInfo->DumpRawFile = AllocateZeroPool (ProgramInfo->DumpRawFileSize);
+ if (ProgramInfo->DumpRawFile == NULL) {
+ Print (L"ERROR: [#%d] Failed to allocate buffer!\n", __LINE__);
+ Status = SHELL_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+
+ //
+ // Read in the image
+ //
+ if (ProgramInfo->DumpRawLibraryIndex == EEPROM_EEPROM) {
+ FunctionInfo = (VOID *) &EepromInfo;
+ }
+ EfiStatus = ReadEeprom (ProgramInfo->DumpRawLibraryIndex, 0, &ProgramInfo->DumpRawFileSize, ProgramInfo->DumpRawFile, FunctionInfo);
+ if (EFI_ERROR (EfiStatus)) {
+ Print (L"ERROR: [#%d] Failed to read image file (%r)!\n", __LINE__, EfiStatus);
+ Status = SHELL_DEVICE_ERROR;
+ goto Exit;
+ }
+ }
+
+ //
+ // Dump the image
+ //
+ DumpParagraph (ProgramInfo->DumpRawFile, ProgramInfo->DumpRawFileSize);
+
+ //
+ // Set exit value
+ //
+ Status = SHELL_SUCCESS;
+
+Exit:
+ return Status;
+}
+
+SHELL_STATUS
+EraseOption (
+ IN PROGRAM_INFO *ProgramInfo
+ )
+{
+ EFI_STATUS EfiStatus;
+ SHELL_STATUS Status;
+
+ if (gDebugFlag) Print (L"%a(#%d) - Starting...\n", __FUNCTION__, __LINE__);
+
+ //
+ // Initialize variables
+ //
+ Status = SHELL_SUCCESS;
+
+ EfiStatus = EraseEeprom (ProgramInfo->EraseLibraryIndex);
+ if (EFI_ERROR (EfiStatus)) {
+ Print (L"ERROR: [#%d] Failed to erase image file (%r)!\n", __LINE__, EfiStatus);
+ Status = SHELL_DEVICE_ERROR;
+ }
+ return Status;
+}
+
+UINTN
+GetHexOrDecFromString (
+ CHAR16 *Arg
+ )
+{
+ CHAR16 Str[2];
+
+ Str[0] = Arg[0];
+ Str[1] = Arg[1];
+
+ if (StrCmp (Str, L"0x") == 0 ||
+ StrCmp (Str, L"0X") == 0) {
+ return StrHexToUintn (Arg);
+ } else{
+ return StrDecimalToUintn (Arg);
+ }
+}
+
+VOID
+ParseParameters (
+ IN UINTN Argc,
+ IN CHAR16 **Argv,
+ IN PROGRAM_INFO *ProgramInfo
+ )
+{
+ EFI_STATUS EfiStatus;
+ UINTN Index;
+
+ if (gDebugFlag) Print (L"%a(#%d) - Starting...\n", __FUNCTION__, __LINE__);
+
+ // Sanity checks
+ if ((Argv == NULL) || (ProgramInfo == NULL)) {
+ if (gDebugFlag) Print (L"ERROR: [#%d] Internal coding error!\n", __LINE__);
+ goto Exit;
+ }
+
+ // Clear ProgramInfo
+ ZeroMem (ProgramInfo, sizeof (ProgramInfo));
+
+ for (Index = 1; Index < Argc; Index++) {
+ // Convert to lowercase for easier parsing
+ ToLower (Argv[Index]);
+
+ // Check for Debug option
+ if (StrCmp (Argv[Index], L"--debug") == 0) {
+ // Debug option detected
+ gDebugFlag = TRUE;
+ Print (L"Enabling debug mode...\n");
+ } else
+
+ // Check for Help option
+ if ((StrCmp (Argv[Index], L"-h") == 0) ||
+ (StrCmp (Argv[Index], L"--help") == 0) ||
+ (StrCmp (Argv[Index], L"-?") == 0)) {
+ // Help option detected
+ ProgramInfo->HelpFlag = TRUE;
+ } else
+
+ // Check for Address option
+ if ((StrCmp (Argv[Index], L"-a") == 0) || (StrCmp (Argv[Index], L"--address") == 0)) {
+ // Address option detected
+ ProgramInfo->AddressFlag = TRUE;
+ if (Index + 1 < Argc) {
+ // Get Slave address
+ if (Argv[Index + 1][0] != L'-') {
+ ProgramInfo->AddressValue = (UINT8) (GetHexOrDecFromString (Argv[Index + 1]) & 0xFF);
+ Index++;
+ }
+ }
+ } else
+
+ // Check for Bus option
+ if ((StrCmp (Argv[Index], L"-b") == 0) || (StrCmp (Argv[Index], L"--bus") == 0)) {
+ // Bus option detected
+ ProgramInfo->BusFlag = TRUE;
+ if (Index + 1 < Argc) {
+ // Get bus number
+ if (Argv[Index + 1][0] != L'-') {
+ ProgramInfo->BusValue = (UINT8) (GetHexOrDecFromString (Argv[Index + 1]) & 0xFF);
+ Index++;
+ }
+ }
+ } else
+
+ // Check for Check security option
+ if ((StrCmp (Argv[Index], L"-c") == 0) || (StrCmp (Argv[Index], L"--check") == 0)) {
+ // Check security option detected
+ ProgramInfo->CheckFlag = TRUE;
+ if (Index + 1 < Argc) {
+ // Get Library Index
+ if (Argv[Index + 1][0] != L'-') {
+ ProgramInfo->CheckLibraryIndex = (UINT8) (GetHexOrDecFromString (Argv[Index + 1]) & 0xFF);
+ Index++;
+ }
+ }
+ if (Index + 1 < Argc) {
+ // Get Filename
+ if (Argv[Index + 1][0] != L'-') {
+ ProgramInfo->CheckFileName = Argv[Index + 1];
+ Index++;
+ // Read in file
+ ProgramInfo->CheckFile = NULL;
+ EfiStatus = ReadFileData (ProgramInfo->CheckFileName, &ProgramInfo->CheckFile, &ProgramInfo->CheckFileSize);
+ if (EFI_ERROR (EfiStatus)) {
+ Print (L"ERROR: [#%d] Failed to read image file (%r)!\n", __LINE__, EfiStatus);
+ }
+ }
+ }
+ } else
+
+ // Check for Dump raw option
+ if ((StrCmp (Argv[Index], L"-d") == 0) || (StrCmp (Argv[Index], L"--dump") == 0)) {
+ // Dump raw option detected
+ ProgramInfo->DumpRawFlag = TRUE;
+ if (Index + 1 < Argc) {
+ // Get Library Index
+ if (Argv[Index + 1][0] != L'-') {
+ ProgramInfo->DumpRawLibraryIndex = (UINT8) (GetHexOrDecFromString (Argv[Index + 1]) & 0xFF);
+ Index++;
+ }
+ }
+ if (Index + 1 < Argc) {
+ // Get Filename
+ if (Argv[Index + 1][0] != L'-') {
+ ProgramInfo->DumpRawFileName = Argv[Index + 1];
+ Index++;
+ // Read in file
+ ProgramInfo->DumpRawFile = NULL;
+ EfiStatus = ReadFileData (ProgramInfo->DumpRawFileName, &ProgramInfo->DumpRawFile, &ProgramInfo->DumpRawFileSize);
+ if (EFI_ERROR (EfiStatus)) {
+ Print (L"ERROR: [#%d] Failed to read image file (%r)!\n", __LINE__, EfiStatus);
+ }
+ }
+ }
+ } else
+
+ // Check for Dump human option
+ if ((StrCmp (Argv[Index], L"-dh") == 0) || (StrCmp (Argv[Index], L"--dumphuman") == 0)) {
+ // Dump human option detected
+ ProgramInfo->DumpHumanFlag = TRUE;
+ if (Index + 1 < Argc) {
+ // Get Library Index
+ if (Argv[Index + 1][0] != L'-') {
+ ProgramInfo->DumpHumanLibraryIndex = (UINT8) (GetHexOrDecFromString (Argv[Index + 1]) & 0xFF);
+ Index++;
+ }
+ }
+ if (Index + 1 < Argc) {
+ // Get Filename
+ if (Argv[Index + 1][0] != L'-') {
+ ProgramInfo->DumpHumanFileName = Argv[Index + 1];
+ Index++;
+ // Read in file
+ ProgramInfo->DumpHumanFile = NULL;
+ EfiStatus = ReadFileData (ProgramInfo->DumpHumanFileName, &ProgramInfo->DumpHumanFile, &ProgramInfo->DumpHumanFileSize);
+ if (EFI_ERROR (EfiStatus)) {
+ Print (L"ERROR: [#%d] Failed to read image file (%r)!\n", __LINE__, EfiStatus);
+ }
+ }
+ }
+ } else
+
+ // Check for erase option
+ if ((StrCmp (Argv[Index], L"-e") == 0) || (StrCmp (Argv[Index], L"--erase") == 0)) {
+ // Check security option detected
+ ProgramInfo->EraseFlag = TRUE;
+ if (Index + 1 < Argc) {
+ // Get Library Index
+ if (Argv[Index + 1][0] != L'-') {
+ ProgramInfo->EraseLibraryIndex = (UINT8) (GetHexOrDecFromString (Argv[Index + 1]) & 0xFF);
+ Index++;
+ }
+ }
+ } else
+
+ // Check for Read option
+ if ((StrCmp (Argv[Index], L"-r") == 0) || (StrCmp (Argv[Index], L"--read") == 0)) {
+ // Read option detected
+ ProgramInfo->ReadFlag = TRUE;
+ if (Index + 1 < Argc) {
+ // Get Library Index
+ if (Argv[Index + 1][0] != L'-') {
+ ProgramInfo->ReadLibraryIndex = (UINT8) (GetHexOrDecFromString (Argv[Index + 1]) & 0xFF);
+ Index++;
+ }
+ }
+ if (Index + 1 < Argc) {
+ // Get Filename
+ if (Argv[Index + 1][0] != L'-') {
+ ProgramInfo->ReadFileName = Argv[Index + 1];
+ Index++;
+ }
+ }
+ } else
+
+ // Check for Scan option
+ if ((StrCmp (Argv[Index], L"-s") == 0) || (StrCmp (Argv[Index], L"--scan") == 0)) {
+ // Scan option detected
+ ProgramInfo->ScanFlag = TRUE;
+ } else
+
+ // Check for Verbose option
+ if ((StrCmp (Argv[Index], L"--verbose") == 0)) {
+ // Verbose option detected
+ ProgramInfo->VerboseFlag = TRUE;
+ } else
+
+ // Check for Verify option
+ if ((StrCmp (Argv[Index], L"-v") == 0) || (StrCmp (Argv[Index], L"--verify") == 0)) {
+ // Verify option detected
+ ProgramInfo->VerifyFlag = TRUE;
+ if (Index + 1 < Argc) {
+ // Get Library Index
+ if (Argv[Index + 1][0] != L'-') {
+ ProgramInfo->VerifyLibraryIndex = (UINT8) (GetHexOrDecFromString (Argv[Index + 1]) & 0xFF);
+ Index++;
+ }
+ }
+ if (Index + 1 < Argc) {
+ // Get Filename
+ if (Argv[Index + 1][0] != L'-') {
+ ProgramInfo->VerifyFileName = Argv[Index + 1];
+ Index++;
+ // Read in file
+ ProgramInfo->VerifyFile = NULL;
+ EfiStatus = ReadFileData (ProgramInfo->VerifyFileName, &ProgramInfo->VerifyFile, &ProgramInfo->VerifyFileSize);
+ if (EFI_ERROR (EfiStatus)) {
+ Print (L"ERROR: [#%d] Failed to read image file (%r)!\n", __LINE__, EfiStatus);
+ }
+ }
+ }
+ } else
+
+ // Check for Write option
+ if ((StrCmp (Argv[Index], L"-w") == 0) || (StrCmp (Argv[Index], L"--write") == 0)) {
+ // Write option detected
+ ProgramInfo->WriteFlag = TRUE;
+ if (Index + 1 < Argc) {
+ // Get Library Index
+ if (Argv[Index + 1][0] != L'-') {
+ ProgramInfo->WriteLibraryIndex = (UINT8) (GetHexOrDecFromString (Argv[Index + 1]) & 0xFF);
+ Index++;
+ }
+ }
+ if (Index + 1 < Argc) {
+ // Get Filename
+ if (Argv[Index + 1][0] != L'-') {
+ ProgramInfo->WriteFileName = Argv[Index + 1];
+ Index++;
+ // Read in file
+ ProgramInfo->WriteFile = NULL;
+ EfiStatus = ReadFileData (ProgramInfo->WriteFileName, &ProgramInfo->WriteFile, &ProgramInfo->WriteFileSize);
+ if (EFI_ERROR (EfiStatus)) {
+ Print (L"ERROR: [#%d] Failed to read image file (%r)!\n", __LINE__, EfiStatus);
+ }
+ }
+ }
+ } else
+
+ // All that's left is Unknown
+ {
+ // Unkown option
+ Print (L"Unknown! - Argv[%d]: \"%s\"\n", Index, Argv[Index]);
+ }
+ }
+
+Exit:
+ return;
+}
+
+VOID
+PrintChar (
+ IN UINT8 Count,
+ IN CHAR16 *Char
+)
+{
+ UINTN Index;
+
+ // Check for invalid conditions
+ if (Char == NULL) {
+ Print (L"ERROR: [#%d] Internal coding error!\n", __LINE__);
+ goto Exit;
+ }
+
+ for (Index = 0; Index < Count; Index++) {
+ Print (L"%s", Char);
+ }
+
+Exit:
+ return;
+}
+
+VOID
+PrintHelp (VOID)
+{
+ Print (L" EepromApp.efi is a tool to read/write/dump the EERPOM data.\n");
+ Print (L"\n");
+ Print (L" Switches:\n");
+ Print (L" -a # Sets the I2C slave address (7-bit).\n");
+ Print (L" -b # Sets the I2C bus number.\n");
+ Print (L" -c # filename Check security of the image.\n");
+ Print (L" -d # filename Dumps the image in raw format.\n");
+ Print (L" -dh # filename Dumps the image in human readable format.\n");
+ Print (L" -e # Erase that image.\n");
+ Print (L" -h Dumps this help info.\n");
+ Print (L" -r # filename Reads the image from the library index into the file.\n");
+ Print (L" - This reads the entire EEPROM part, not just the image.\n");
+ Print (L" -s Scans all of the buses looking for images.\n");
+ Print (L" -v # filename Verifies the image in library index with the file.\n");
+ Print (L" --verbose Turns on verbosity.\n");
+ Print (L" -w # filename Writes the image from the file to the library index.\n");
+ Print (L"\n");
+ Print (L" Library:\n");
+ Print (L" 0 - Null library\n");
+ Print (L" 1 - EEPROM library\n");
+ Print (L" 2 - FV library\n");
+ Print (L" 3 - Memory library\n");
+ Print (L"\n");
+ Print (L" Examples:\n");
+ Print (L" EepromApp.efi -b 6 -a 0x53 -d 1 - Dump the EEPROM image in raw\n");
+ Print (L" format from I2C #6, 0x53.\n");
+ Print (L" EepromApp.efi -r 3 Test.bin - Write the memory image to\n");
+ Print (L" Test.bin.\n");
+ Print (L" EepromApp.efi -s -w 1 Test.bin - Write Test.bin to the EERPOM\n");
+ Print (L" last found during the scan.\n");
+ Print (L" EepromApp.efi -b 4 -a 0x5F -w 1 Test.bin - Write Test.bin to the EERPOM\n");
+ Print (L" on I2C #4, 0x5F.\n");
+ Print (L" EepromApp.efi -dh 0 Test.bin - Dump Test.bin in human\n");
+ Print (L" readable form.\n");
+ Print (L" EepromApp.efi -s -c 1 - Scan the EEPROM buses for\n");
+ Print (L" images and check the security\n");
+ Print (L" of the last one found.\n");
+ Print (L"\n");
+}
+
+//
+// Read data from file
+//
+EFI_STATUS
+ReadFileData (
+ IN CHAR16 *FileName,
+ OUT UINT8 **Buffer,
+ OUT UINT32 *BufferSize
+ )
+{
+ EFI_STATUS Status;
+ SHELL_FILE_HANDLE FileHandle;
+ UINT64 Size;
+ VOID *NewBuffer;
+ UINTN ReadSize;
+
+ if (gDebugFlag) Print (L"%a(#%d) - Starting...\n", __FUNCTION__, __LINE__);
+
+ //
+ // Initialize variables
+ //
+ FileHandle = NULL;
+ NewBuffer = NULL;
+ Size = 0;
+
+ //
+ // Sanity checks
+ //
+ if (FileName == NULL) {
+ if (gDebugFlag) Print (L"ERROR: [#%d] FileName not set!\n", __LINE__);
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ if (Buffer == NULL) {
+ if (gDebugFlag) Print (L"ERROR: [#%d] Buffer pointer is NULL!\n", __LINE__);
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ if (*Buffer != NULL) {
+ if (gDebugFlag) Print (L"ERROR: [#%d] *Buffer pointer is not NULL!\n", __LINE__);
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+
+ //
+ // Open file
+ //
+ Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ, 0);
+ if (EFI_ERROR (Status)) {
+ Print (L"ERROR: [#%d] Failed to open file %s (%r)\n", __LINE__, FileName, Status);
+ goto Exit;
+ }
+
+ //
+ // Sanity check to make sure it isn't a directory
+ //
+ Status = FileHandleIsDirectory (FileHandle);
+ if (!EFI_ERROR (Status)) {
+ Print (L"ERROR: [#%d] Failed to determine if %s was a directory (%r)\n", __LINE__, FileName, Status);
+ Status = EFI_NOT_FOUND;
+ goto Exit;
+ }
+
+ //
+ // Get file size
+ //
+ Status = FileHandleGetSize (FileHandle, &Size);
+ if (EFI_ERROR (Status)) {
+ Print (L"ERROR: [#%d] Failed to get size of %s (%r)\n", __LINE__, FileName, Status);
+ goto Exit;
+ }
+
+ //
+ // Allocate buffer
+ //
+ NewBuffer = AllocatePool ((UINTN) Size);
+
+ //
+ // Read in file
+ //
+ ReadSize = (UINTN) Size;
+ Status = FileHandleRead (FileHandle, &ReadSize, NewBuffer);
+ if (EFI_ERROR (Status)) {
+ Print (L"ERROR: [#%d] Failed to read %s (%r)\n", __LINE__, FileName, Status);
+ goto Exit;
+ } else if (ReadSize != (UINTN) Size) {
+ Print (L"ERROR: [#%d] Failed to read the right number of bytes. Should have been %08x and read %08x\n", __LINE__, Size, ReadSize);
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+
+Exit:
+ //
+ // Free resources
+ //
+ if (FileHandle != NULL) {
+ ShellCloseFile (&FileHandle);
+ }
+
+ //
+ // Set output contents
+ //
+ if (!EFI_ERROR (Status)) {
+ *BufferSize = (UINT32) Size;
+ *Buffer = NewBuffer;
+ } else {
+ *BufferSize = 0;
+ *Buffer = NULL;
+ }
+
+ return Status;
+}
+
+SHELL_STATUS
+ReadOption (
+ IN PROGRAM_INFO *ProgramInfo
+ )
+{
+ EEPROM_FUNCTION_INFO EepromInfo;
+ EFI_STATUS EfiStatus;
+ VOID *FunctionInfo;
+ SHELL_STATUS Status;
+
+ if (gDebugFlag) Print (L"%a(#%d) - Starting...\n", __FUNCTION__, __LINE__);
+
+ //
+ // Initialize variables
+ //
+ ZeroMem (&EepromInfo, sizeof (EEPROM_FUNCTION_INFO));
+ EepromInfo.Bus = ProgramInfo->BusValue;
+ EepromInfo.Address = ProgramInfo->AddressValue;
+ EepromInfo.LibraryIndex = EEPROM_EEPROM;
+ FunctionInfo = NULL;
+ Status = SHELL_SUCCESS;
+
+ //
+ // Sanity checks
+ //
+ if (ProgramInfo == NULL) {
+ if (gDebugFlag) Print (L"ERROR: [#%d] Internal coding error!\n", __LINE__);
+ Status = SHELL_INVALID_PARAMETER;
+ goto Exit;
+ }
+
+ //
+ // Find out the size of the image
+ //
+ Print (L" - Reading %a to %s", mEepromLibraryString[ProgramInfo->ReadLibraryIndex], ProgramInfo->ReadFileName);
+ if (ProgramInfo->ReadLibraryIndex == EEPROM_EEPROM) {
+ Print (L" via bus #%d @ 0x%02x", ProgramInfo->BusValue, ProgramInfo->AddressValue);
+ FunctionInfo = (VOID *) &EepromInfo;
+ }
+ Print (L"...\n");
+ ProgramInfo->ReadFileSize = GetImageSize (ProgramInfo->ReadLibraryIndex);
+ ProgramInfo->ReadFile = AllocateZeroPool (ProgramInfo->ReadFileSize);
+ if (ProgramInfo->ReadFile == NULL) {
+ Print (L"ERROR: [#%d] Failed to allocate buffer!\n", __LINE__);
+ Status = SHELL_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+
+ //
+ // Fill buffer from library
+ //
+ EfiStatus = ReadEeprom (ProgramInfo->ReadLibraryIndex, 0, &ProgramInfo->ReadFileSize, ProgramInfo->ReadFile, FunctionInfo);
+ if (EFI_ERROR (EfiStatus)) {
+ Print (L"ERROR: [#%d] Failed to read image file (%r)!\n", __LINE__, EfiStatus);
+ Status = SHELL_DEVICE_ERROR;
+ goto Exit;
+ }
+
+ //
+ // Write out the image file
+ //
+ EfiStatus = WriteFileData (ProgramInfo->ReadFileName, ProgramInfo->ReadFile, ProgramInfo->ReadFileSize);
+ if (EFI_ERROR (EfiStatus)) {
+ Print (L"ERROR: [#%d] Failed to write image file (%r)!\n", __LINE__, EfiStatus);
+ Status = SHELL_DEVICE_ERROR;
+ goto Exit;
+ }
+
+ Print (L" - Image %a written to %s\n", mEepromLibraryString[ProgramInfo->ReadLibraryIndex], ProgramInfo->ReadFileName);
+
+Exit:
+ //
+ // Free resources
+ //
+ return Status;
+}
+
+SHELL_STATUS
+ScanOption (
+ IN PROGRAM_INFO *ProgramInfo
+ )
+{
+ UINT8 Buffer[2];
+ UINT8 Bus;
+ EEPROM_FUNCTION_INFO EepromInfo;
+ EFI_STATUS EfiStatus;
+ UINT8 index;
+ UINT8 ScanSize;
+ UINT32 Size;
+ SHELL_STATUS Status;
+
+ if (gDebugFlag) Print (L"%a(#%d) - Starting...\n", __FUNCTION__, __LINE__);
+
+ //
+ // Initialize variables
+ //
+ ZeroMem (&EepromInfo, sizeof (EEPROM_FUNCTION_INFO));
+ EepromInfo.LibraryIndex = EEPROM_EEPROM;
+ ScanSize = 0;
+ Size = 0;
+ Status = SHELL_NOT_FOUND;
+
+ //
+ // Loop thru I2C buses for images
+ //
+ EepromInfo.ScanSize = &ScanSize;
+ for (Bus = 0; Bus < 8; Bus++) {
+ if (gDebugFlag) Print (L" - Scanning bus #%d\n", Bus);
+ EepromInfo.Bus = Bus;
+ ScanSize = 0;
+ EfiStatus = ReadEeprom (EEPROM_EEPROM, 0, &Size, Buffer, &EepromInfo);
+ if (!EFI_ERROR (EfiStatus)) {
+ //
+ // Dump any images found
+ //
+ Status = SHELL_SUCCESS;
+ for (index = 0; index < ScanSize; index++) {
+ Print (L" - Found image on I2C bus #%d, address 0x%02x\n", Bus, EepromInfo.ScanBuffer[index]);
+ ProgramInfo->BusFlag = TRUE;
+ ProgramInfo->BusValue = Bus;
+ ProgramInfo->AddressFlag = TRUE;
+ ProgramInfo->AddressValue = EepromInfo.ScanBuffer[index];
+ }
+ }
+ }
+
+ //
+ // Free resources
+ //
+ if (EepromInfo.ScanBuffer != NULL) {
+ FreePool (EepromInfo.ScanBuffer);
+ EepromInfo.ScanBuffer = NULL;
+ }
+
+ return Status;
+}
+
+/**
+ Convert a null-terminated unicode string, in-place, to all lowercase.
+ Then return it.
+
+ @param Str The null-terminated string to be converted to all lowercase.
+
+ @return The null-terminated string converted into all lowercase.
+**/
+CHAR16 *
+ToLower (
+ IN OUT CHAR16 *Str
+ )
+{
+ UINTN Index;
+
+ // Check for invalid conditions
+ if (Str == NULL) {
+ if (gDebugFlag) Print (L"ERROR: [#%d] Internal coding error!\n", __LINE__);
+ goto Exit;
+ }
+
+ for (Index = 0; Str[Index] != L'\0'; Index++) {
+ if ((Str[Index] >= L'A') && (Str[Index] <= L'Z')) {
+ Str[Index] -= (CHAR16)(L'A' - L'a');
+ }
+ }
+
+Exit:
+ return Str;
+}
+
+SHELL_STATUS
+VerifyOption (
+ IN PROGRAM_INFO *ProgramInfo
+ )
+{
+ EEPROM_FUNCTION_INFO EepromInfo;
+ EFI_STATUS EfiStatus;
+ VOID *FunctionInfo;
+ UINT8 *ImageBuffer;
+ UINT32 ImageSize;
+ UINT32 index;
+ SHELL_STATUS Status;
+
+ if (gDebugFlag) Print (L"%a(#%d) - Starting...\n", __FUNCTION__, __LINE__);
+
+ //
+ // Initialize variables
+ //
+ ZeroMem (&EepromInfo, sizeof (EEPROM_FUNCTION_INFO));
+ EepromInfo.Bus = ProgramInfo->BusValue;
+ EepromInfo.Address = ProgramInfo->AddressValue;
+ EepromInfo.LibraryIndex = EEPROM_EEPROM;
+ FunctionInfo = NULL;
+ ImageBuffer = NULL;
+ Status = SHELL_SUCCESS;
+
+ //
+ // Sanity checks
+ //
+ if (ProgramInfo == NULL) {
+ if (gDebugFlag) Print (L"ERROR: [#%d] Internal coding error!\n", __LINE__);
+ Status = SHELL_INVALID_PARAMETER;
+ goto Exit;
+ }
+ if ((ProgramInfo->VerifyFile == NULL) || (ProgramInfo->VerifyFileSize == 0)) {
+ if (gDebugFlag) Print (L"ERROR: [#%d] Image file is empty!\n", __LINE__);
+ Status = SHELL_INVALID_PARAMETER;
+ goto Exit;
+ }
+
+ //
+ // Find out the size of the image
+ //
+ Print (L" - Comparing %s to %a", ProgramInfo->VerifyFileName, mEepromLibraryString[ProgramInfo->VerifyLibraryIndex]);
+ if (ProgramInfo->VerifyLibraryIndex == EEPROM_EEPROM) {
+ Print (L" via bus #%d @ 0x%02x", ProgramInfo->BusValue, ProgramInfo->AddressValue);
+ FunctionInfo = (VOID *) &EepromInfo;
+ }
+ Print (L"...\n");
+ ImageSize = GetImageSize (ProgramInfo->VerifyLibraryIndex);
+ ImageBuffer = AllocateZeroPool (ImageSize);
+ if (ImageBuffer == NULL) {
+ Print (L"ERROR: [#%d] Failed to allocate buffer!\n", __LINE__);
+ Status = SHELL_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+
+ //
+ // Read in the memory image
+ //
+ EfiStatus = ReadEeprom (ProgramInfo->VerifyLibraryIndex, 0, &ImageSize, ImageBuffer, FunctionInfo);
+ if (EFI_ERROR (EfiStatus)) {
+ Print (L"ERROR: [#%d] Failed to read image file (%r)!\n", __LINE__, EfiStatus);
+ Status = SHELL_DEVICE_ERROR;
+ goto Exit;
+ }
+
+ //
+ // Compare images
+ //
+ if ((ImageSize != ProgramInfo->VerifyFileSize) && (ProgramInfo->VerifyLibraryIndex != EEPROM_EEPROM)) {
+ Print (L"ERROR: [#%d] Image size does not match file size!\n", __LINE__);
+ Status = SHELL_DEVICE_ERROR;
+ goto Exit;
+ }
+ for (index = 0; index < ImageSize; index++) {
+ if (ProgramInfo->VerifyFile[index] != ImageBuffer[index]) {
+ if (((index + 1) > ProgramInfo->VerifyFileSize) && (ProgramInfo->VerifyLibraryIndex == EEPROM_EEPROM)) {
+ //
+ // Getting image size from ReadEeprom with a size of 0 for EEPROM_EEPROM will return the size of the part, not the image.
+ //
+ break;
+ } else {
+ Print (L"ERROR: [#%d] Failed to verify file & image @ %08x [%02x:%02x]\n", __LINE__, index, ProgramInfo->VerifyFile[index], ImageBuffer[index]);
+ Status = SHELL_DEVICE_ERROR;
+ goto Exit;
+ }
+ }
+ }
+ Print (L" - Image %s compared to %a successfully\n", ProgramInfo->VerifyFileName, mEepromLibraryString[ProgramInfo->VerifyLibraryIndex]);
+
+Exit:
+ //
+ // Free resources
+ //
+ if (ImageBuffer != NULL) {
+ FreePool (ImageBuffer);
+ ImageBuffer = NULL;
+ }
+ return Status;
+}
+
+EFI_STATUS
+WriteFileData (
+ IN CHAR16 *FileName,
+ IN UINT8 *Buffer,
+ IN UINTN BufferSize
+ )
+{
+ SHELL_FILE_HANDLE FileHandle;
+ EFI_STATUS Status;
+
+ if (gDebugFlag) Print (L"%a(#%d) - Starting...\n", __FUNCTION__, __LINE__);
+
+ //
+ // Sanity checks
+ //
+ if (FileName == NULL) {
+ if (gDebugFlag) Print (L"ERROR: [#%d] FileName not set!\n", __LINE__);
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ if (Buffer == NULL) {
+ if (gDebugFlag) Print (L"ERROR: [#%d] Buffer pointer is NULL!\n", __LINE__);
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+
+ //
+ // Is the requested file a directory?
+ //
+ if (ShellIsDirectory (FileName) == EFI_SUCCESS) {
+ Print (L"ERROR: [#%d] File is a directory! Can not be saved.\n", __LINE__);
+ Status = EFI_LOAD_ERROR;
+ goto Exit;
+ }
+
+ //
+ // If file exists, delete it
+ //
+ Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE, 0);
+ if (!EFI_ERROR (Status)) {
+ //
+ // the file exits, delete it
+ //
+ Status = ShellDeleteFile (&FileHandle);
+ if (EFI_ERROR (Status) || Status == EFI_WARN_DELETE_FAILURE) {
+ Print (L"ERROR: [#%d] Deleteing existing file failed!\n", __LINE__);
+ Status = EFI_LOAD_ERROR;
+ goto Exit;
+ }
+ }
+
+ //
+ // Create file
+ //
+ Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, 0);
+ if (EFI_ERROR (Status)) {
+ Print (L"ERROR: [#%d] Creating file failed!\n", __LINE__);
+ Status = EFI_LOAD_ERROR;
+ goto Exit;
+ }
+
+ //
+ // Write buffer to file
+ //
+ Status = ShellWriteFile (FileHandle, &BufferSize, Buffer);
+ if (EFI_ERROR (Status)) {
+ ShellDeleteFile (&FileHandle);
+ Status = EFI_LOAD_ERROR;
+ goto Exit;
+ }
+
+ Status = EFI_SUCCESS;
+
+Exit:
+ //
+ // Free resources
+ //
+ if (FileHandle != NULL) {
+ ShellCloseFile (&FileHandle);
+ }
+
+ return Status;
+}
+
+SHELL_STATUS
+WriteOption (
+ IN PROGRAM_INFO *ProgramInfo
+ )
+{
+ EEPROM_FUNCTION_INFO EepromInfo;
+ EFI_STATUS EfiStatus;
+ VOID *FunctionInfo;
+ SHELL_STATUS Status;
+
+ if (gDebugFlag) Print (L"%a(#%d) - Starting...\n", __FUNCTION__, __LINE__);
+
+ //
+ // Initialize variables
+ //
+ ZeroMem (&EepromInfo, sizeof (EEPROM_FUNCTION_INFO));
+ EepromInfo.Bus = ProgramInfo->BusValue;
+ EepromInfo.Address = ProgramInfo->AddressValue;
+ EepromInfo.LibraryIndex = EEPROM_EEPROM;
+ FunctionInfo = NULL;
+ Status = SHELL_SUCCESS;
+
+ //
+ // Sanity checks
+ //
+ if (ProgramInfo == NULL) {
+ if (gDebugFlag) Print (L"ERROR: [#%d] Internal coding error!\n", __LINE__);
+ Status = SHELL_INVALID_PARAMETER;
+ goto Exit;
+ }
+ if ((ProgramInfo->WriteFile == NULL) || (ProgramInfo->WriteFileSize == 0)) {
+ if (gDebugFlag) Print (L"ERROR: [#%d] Image file is empty!\n", __LINE__);
+ Status = SHELL_INVALID_PARAMETER;
+ goto Exit;
+ }
+
+ //
+ // Write image out
+ //
+ Print (L" - Writing %s to %a", ProgramInfo->WriteFileName, mEepromLibraryString[ProgramInfo->WriteLibraryIndex]);
+ if (ProgramInfo->WriteLibraryIndex == EEPROM_EEPROM) {
+ Print (L" via bus #%d @ 0x%02x", ProgramInfo->BusValue, ProgramInfo->AddressValue);
+ FunctionInfo = (VOID *) &EepromInfo;
+ }
+ Print (L"...\n");
+ EfiStatus = WriteEeprom (ProgramInfo->WriteLibraryIndex, 0, &ProgramInfo->WriteFileSize, ProgramInfo->WriteFile, FunctionInfo);
+ if (EFI_ERROR (EfiStatus)) {
+ Print (L"ERROR: [#%d] Failed to write image file (%r)!\n", __LINE__, EfiStatus);
+ Status = SHELL_DEVICE_ERROR;
+ goto Exit;
+ }
+ Print (L" - Image %s written to %a\n", ProgramInfo->WriteFileName, mEepromLibraryString[ProgramInfo->WriteLibraryIndex]);
+
+ //
+ // Validate image
+ //
+ Print (L" - Validating image...\n");
+ EfiStatus = ValidateEeprom (ProgramInfo->WriteLibraryIndex);
+ Print (L" - Image validation status = %r\n", EfiStatus);
+
+Exit:
+ return Status;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromApp/EepromApp.h b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromApp/EepromApp.h
new file mode 100644
index 0000000000..7babb6555e
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromApp/EepromApp.h
@@ -0,0 +1,196 @@
+/** @file
+
+ This application will read/write/verify/dump the EERPOM data.
+
+ 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.
+
+
+**/
+
+#ifndef _EEPROM_APP_H_
+#define _EEPROM_APP_H_
+
+#include <Uefi.h>
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/EepromDataLib.h>
+#include <Library/EepromLib.h>
+#include <Library/FileHandleLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PrintLib.h>
+#include <Library/ShellCEntryLib.h>
+#include <Library/ShellLib.h>
+#include <Library/TimerLib.h>
+#include <Library/UefiLib.h>
+
+// Defines
+#define APP_VERSION L"1.00.00"
+#define APP_COPYRIGHT L"2017 - 2018"
+#define DIVIDING_LINE L"+----------------------------------------------------+------------------+\n"
+
+#define MD5DigestSize 0x10
+#define SHA1DigestSize 0x14
+#define SHA256DigestSize 0x20
+#define SHA384DigestSize 0x30
+#define SHA512DigestSize 0x40
+
+// Structures
+typedef struct {
+ BOOLEAN HelpFlag;
+ BOOLEAN AddressFlag;
+ UINT8 AddressValue;
+ BOOLEAN BusFlag;
+ UINT8 BusValue;
+ BOOLEAN CheckFlag;
+ UINT8 CheckLibraryIndex;
+ UINT8 *CheckFile;
+ CHAR16 *CheckFileName;
+ UINT32 CheckFileSize;
+ BOOLEAN DumpHumanFlag;
+ UINT8 DumpHumanLibraryIndex;
+ UINT8 *DumpHumanFile;
+ CHAR16 *DumpHumanFileName;
+ UINT32 DumpHumanFileSize;
+ BOOLEAN DumpRawFlag;
+ UINT8 DumpRawLibraryIndex;
+ UINT8 *DumpRawFile;
+ CHAR16 *DumpRawFileName;
+ UINT32 DumpRawFileSize;
+ BOOLEAN EraseFlag;
+ UINT8 EraseLibraryIndex;
+ BOOLEAN ReadFlag;
+ UINT8 ReadLibraryIndex;
+ UINT8 *ReadFile;
+ CHAR16 *ReadFileName;
+ UINT32 ReadFileSize;
+ BOOLEAN ScanFlag;
+ BOOLEAN VerboseFlag;
+ BOOLEAN VerifyFlag;
+ UINT8 VerifyLibraryIndex;
+ UINT8 *VerifyFile;
+ CHAR16 *VerifyFileName;
+ UINT32 VerifyFileSize;
+ BOOLEAN WriteFlag;
+ UINT8 WriteLibraryIndex;
+ UINT8 *WriteFile;
+ CHAR16 *WriteFileName;
+ UINT32 WriteFileSize;
+} PROGRAM_INFO;
+
+// Headers
+SHELL_STATUS
+BufferToMemory (
+ IN UINT8 *Buffer,
+ IN UINT32 BufferSize,
+ OUT UINT8 **MemoryBuffer,
+ OUT UINT32 *MemoryBufferSize
+ );
+
+SHELL_STATUS
+CheckForInvalidOptions (
+ IN PROGRAM_INFO *ProgramInfo
+ );
+
+SHELL_STATUS
+CheckOption (
+ IN PROGRAM_INFO *ProgramInfo
+ );
+
+SHELL_STATUS
+DumpHumanOption (
+ IN PROGRAM_INFO *ProgramInfo
+ );
+
+VOID
+DumpParagraph (
+ IN VOID *Ptr,
+ IN UINTN Count
+ );
+
+VOID
+DumpProgramInfo (
+ IN PROGRAM_INFO *ProgramInfo
+ );
+
+SHELL_STATUS
+DumpRawOption (
+ IN PROGRAM_INFO *ProgramInfo
+ );
+
+SHELL_STATUS
+EraseOption (
+ IN PROGRAM_INFO *ProgramInfo
+ );
+
+UINTN
+GetHexOrDecFromString (
+ CHAR16 *Arg
+ );
+
+VOID
+ParseParameters (
+ IN UINTN Argc,
+ IN CHAR16 **Argv,
+ IN PROGRAM_INFO *ProgramInfo
+ );
+
+VOID
+PrintChar (
+ IN UINT8 Count,
+ IN CHAR16 *Char
+);
+
+VOID
+PrintHelp (VOID);
+
+EFI_STATUS
+ReadFileData (
+ IN CHAR16 *FileName,
+ OUT UINT8 **Buffer,
+ OUT UINT32 *BufferSize
+ );
+
+SHELL_STATUS
+ReadOption (
+ IN PROGRAM_INFO *ProgramInfo
+ );
+
+SHELL_STATUS
+ScanOption (
+ IN PROGRAM_INFO *ProgramInfo
+ );
+
+CHAR16 *
+ToLower (
+ IN OUT CHAR16 *Str
+ );
+
+SHELL_STATUS
+VerifyOption (
+ IN PROGRAM_INFO *ProgramInfo
+ );
+
+EFI_STATUS
+WriteFileData (
+ IN CHAR16 *FileName,
+ IN UINT8 *Buffer,
+ IN UINTN BufferSize
+ );
+
+SHELL_STATUS
+WriteOption (
+ IN PROGRAM_INFO *ProgramInfo
+ );
+
+#endif // _EEPROM_APP_H_
\ No newline at end of file
diff --git a/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromApp/EepromApp.inf b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromApp/EepromApp.inf
new file mode 100644
index 0000000000..a13974891b
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromApp/EepromApp.inf
@@ -0,0 +1,62 @@
+## @file
+#
+# This application will read/write/verify/dump the EERPOM data.
+#
+# 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.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = EepromApp
+ FILE_GUID = 84CF6CBE-EEDC-4219-9CAB-9510B8D9834F
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ ENTRY_POINT = ShellCEntryLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[Sources]
+ EepromApp.c
+ EepromApp.h
+
+[Packages]
+ MdePkg/MdePkg.dec
+ ShellPkg/ShellPkg.dec
+ BroxtonPlatformPkg/PlatformPkg.dec
+ BroxtonSiPkg/BroxtonSiPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ EepromDataLib
+ EepromLib
+ FileHandleLib
+ MemoryAllocationLib
+ PcdLib
+ PrintLib
+ ShellCEntryLib
+ ShellLib
+ TimerLib
+ UefiApplicationEntryPoint
+ UefiLib
+
+[Guids]
+
+[Protocols]
+
+[Pcd]
+
--
2.14.1.windows.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [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
* [Patch][edk2-platforms/devel-IntelAtomProcessorE3900 5/5] EEPROM header files.
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 ` [Patch][edk2-platforms/devel-IntelAtomProcessorE3900 4/5] Common EEPROM library instance zwei4
@ 2018-07-23 2:39 ` 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/Include/EepromStruct.h | 189 +++++++++++++++++++++
.../Features/Eeprom/Include/Guid/EepromVariable.h | 26 +++
.../Eeprom/Include/Library/EepromDataLib.h | 158 +++++++++++++++++
.../Features/Eeprom/Include/Library/EepromLib.h | 110 ++++++++++++
.../Common/Features/Eeprom/ReadMe.txt | 62 +++++++
5 files changed, 545 insertions(+)
create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/Eeprom/Include/EepromStruct.h
create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/Eeprom/Include/Guid/EepromVariable.h
create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/Eeprom/Include/Library/EepromDataLib.h
create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/Eeprom/Include/Library/EepromLib.h
create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/Eeprom/ReadMe.txt
diff --git a/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/Include/EepromStruct.h b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/Include/EepromStruct.h
new file mode 100644
index 0000000000..e3d0fa6199
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/Include/EepromStruct.h
@@ -0,0 +1,189 @@
+/** @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_LAYOUT_H_
+#define _EEPROM_LAYOUT_H_
+
+#pragma pack(1)
+
+typedef struct {
+ CHAR8 signature[8];
+ UINT16 vermajor;
+ UINT16 verminor;
+ UINT32 length;
+}GENERIC_HEADER;
+
+
+typedef struct {
+ CHAR8 signature[8];
+ UINT16 vermajor;
+ UINT16 verminor;
+ UINT32 length;
+ UINT32 structlength;
+ UINT32 crc32;
+ UINT32 crclength;
+ UINT32 version;
+ CHAR8 reserved[16];
+}EEPROM_HEADER;
+
+
+typedef struct {
+ CHAR8 signature[8];
+ UINT16 vermajor;
+ UINT16 verminor;
+ UINT32 length;
+ CHAR8 reserved[16];
+// UINT8 acpitbl[0];
+}ACPI_TABLE;
+
+
+typedef struct {
+ CHAR8 signature[8];
+ UINT16 vermajor;
+ UINT16 verminor;
+ UINT32 length;
+ CHAR8 manuname[16];
+ CHAR8 brdname[16];
+ CHAR8 brdserial[16];
+ UINT32 boardid;
+ UINT32 fabid;
+ UINT32 ecid;
+ UINT8 boardtype;
+ CHAR8 reserved[19];
+}BOARD_INFO_TABLE;
+
+
+typedef struct {
+ CHAR8 signature[8];
+ UINT16 vermajor;
+ UINT16 verminor;
+ UINT32 length;
+ CHAR8 partlabel[16];
+ UINT32 blklength;
+ UINT16 pagesize;
+ UINT32 partsize;
+ UINT8 busnumber;
+ UINT8 master;
+ UINT8 speed;
+ CHAR8 reserved[3];
+// UINT8 mapdata[0];
+}EEPROM_MAP;
+
+
+typedef struct {
+ CHAR8 maplabel[16];
+ UINT32 length;
+ UINT32 offset;
+ UINT8 address;
+ CHAR8 reserved[7];
+}EEPROM_MAP_RECORD;
+
+
+typedef struct {
+ CHAR8 signature[8];
+ UINT16 vermajor;
+ UINT16 verminor;
+ UINT32 length;
+ CHAR8 reserved[16];
+// UINT8 gpiodata[0];
+}GPIO_DATA_HEADER;
+
+
+typedef struct {
+ CHAR8 gpiolabel[16];
+ UINT32 length;
+ UINT32 offset;
+ UINT32 anddata;
+ UINT32 ordata;
+ UINT8 datasize;
+ UINT8 datatype;
+ CHAR8 reserved[14];
+}GPIO_DATA_RECORD;
+
+
+typedef struct {
+ CHAR8 signature[8];
+ UINT16 vermajor;
+ UINT16 verminor;
+ UINT32 length;
+ CHAR8 reserved[16];
+// UINT8 hdacodec[0];
+}HDA_CODEC;
+
+
+typedef struct {
+ CHAR8 signature[8];
+ UINT16 vermajor;
+ UINT16 verminor;
+ UINT32 length;
+ UINT16 spdslot;
+ CHAR8 reserved[14];
+// UINT8 spddata[0];
+}MEMORY_SPD;
+
+
+typedef struct {
+ CHAR8 signature[8];
+ UINT16 vermajor;
+ UINT16 verminor;
+ UINT32 length;
+ CHAR8 nicid[8];
+ CHAR8 macaddr[6];
+ UINT16 nicnum;
+ CHAR8 reserved[16];
+// UINT8 nicdata[0];
+}NIC_INFO;
+
+
+typedef struct {
+ CHAR8 signature[8];
+ UINT16 vermajor;
+ UINT16 verminor;
+ UINT32 length;
+ UINT16 hashtype;
+ CHAR8 reserved[14];
+// UINT8 eepromsig[0];
+}SIGNATURE_DATA;
+
+
+typedef struct {
+ CHAR8 signature[8];
+ UINT16 vermajor;
+ UINT16 verminor;
+ UINT32 length;
+ CHAR8 reserved[16];
+// UINT8 ucodedata[0];
+}MICROCODE;
+
+
+typedef struct {
+ CHAR8 signature[8];
+ UINT16 vermajor;
+ UINT16 verminor;
+ UINT32 length;
+ CHAR8 reserved[16];
+// UINT8 videodata[0];
+}VIDEO_DATA;
+
+
+typedef struct {
+ CHAR8 signature[8];
+ UINT16 vermajor;
+ UINT16 verminor;
+ UINT32 length;
+ CHAR8 reserved[16];
+// UINT8 logodata[0];
+}LOGO_DATA;
+
+#pragma pack()
+#endif
diff --git a/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/Include/Guid/EepromVariable.h b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/Include/Guid/EepromVariable.h
new file mode 100644
index 0000000000..47b0590467
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/Include/Guid/EepromVariable.h
@@ -0,0 +1,26 @@
+/** @file
+ GUIDs used for EEPROM variable code.
+
+ 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.
+
+**/
+
+#ifndef _EEPROM_VARIABLE_H_
+#define _EEPROM_VARIABLE_H_
+
+
+#define EEPROM_VARIABLE_GUID \
+{ 0xEE96CA33, 0x5F59, 0x4594, 0x98, 0x69, 0x07, 0xF7, 0x9A, 0xA3, 0xC0, 0x6F }
+
+extern EFI_GUID gEepromVariableGuid;
+
+#endif
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/Include/Library/EepromDataLib.h b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/Include/Library/EepromDataLib.h
new file mode 100644
index 0000000000..0d71b3d1bc
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/Include/Library/EepromDataLib.h
@@ -0,0 +1,158 @@
+/** @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_
+#define _EEPROM_DATA_LIB_
+////
+//// Header files
+////
+#include <Uefi.h>
+
+
+////
+//// Defines
+////
+
+////
+//// Enums
+////
+typedef enum {
+ EEPROM_NULL = 0,
+ EEPROM_EEPROM = 1,
+ EEPROM_FV = 2,
+ EEPROM_MEMORY = 3,
+ EEPROM_DATA_LIBRARY_INDEX_MAX = 4
+} EEPROM_DATA_LIBRARY_TYPE;
+
+
+////
+//// Externs
+////
+extern BOOLEAN mEepromDataLibDebugFlag;
+extern CHAR8 *mEepromLibraryString[EEPROM_DATA_LIBRARY_INDEX_MAX];
+
+
+////
+//// Structures
+////
+typedef struct {
+ UINT8 LibraryIndex;
+ UINT8 Address;
+ UINT8 Bus;
+ UINT32 Size; // NOTE: Set this to 0x00.
+ UINT8 *Buffer; // NOTE: Set this to NULL.
+ UINT8 *ScanBuffer; // NOTE: Should be NULL unless requesting a scan on that I2C bus
+ UINT8 *ScanSize; // NOTE: Should be NULL unless requesting a scan on that I2C bus
+} EEPROM_FUNCTION_INFO;
+
+//
+// Should only use this if you need to get a different file from the FV.
+//
+typedef struct {
+ UINT8 LibraryIndex;
+ EFI_GUID *FvFileGuid;
+} FV_FUNCTION_INFO;
+
+
+////
+//// Functions
+////
+//
+// 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
+ );
+
+//
+// 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
+ );
+
+EFI_STATUS
+EFIAPI
+EepromDataLibNemToMemory (VOID);
+
+//
+// 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
+ );
+
+//
+// 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
+ );
+
+//
+// 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
+// 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 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
+ );
+
+#endif // _EEPROM_DATA_LIB_
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/Include/Library/EepromLib.h b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/Include/Library/EepromLib.h
new file mode 100644
index 0000000000..b386e8c7bc
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/Include/Library/EepromLib.h
@@ -0,0 +1,110 @@
+/** @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_
+#define _EEPROM_LIB_
+////
+//// Header files
+////
+#include <Uefi.h>
+
+#include <EepromStruct.h>
+
+
+////
+//// defines
+////
+#define EEPROM_SIGNATURE_SIZE 9
+
+
+////
+//// Enums
+////
+typedef enum {
+ HASH_NONE = 0,
+ HASH_MD5 = 1,
+ HASH_SHA1 = 2,
+ HASH_SHA256 = 3,
+ HASH_SHA384 = 4,
+ HASH_SHA512 = 5
+} EEPROM_HASH_TYPE;
+
+
+////
+//// Functions
+////
+UINTN
+EFIAPI
+DisplayStackPointer (
+ IN CHAR8 *Function,
+ IN UINTN LineNumber
+ );
+
+EFI_STATUS
+EFIAPI
+EraseEeprom (
+ IN UINT8 LibraryIndex
+ );
+
+EFI_STATUS
+EFIAPI
+GetEepromStructure (
+ IN UINT8 LibraryIndex,
+ IN OUT CHAR8 Signature[EEPROM_SIGNATURE_SIZE],
+ IN OUT UINT8 **Buffer,
+ IN OUT UINT32 *Size
+ );
+
+UINT32
+EFIAPI
+GetImageSize (
+ IN UINT8 LibraryIndex
+ );
+
+EFI_STATUS
+EFIAPI
+GetNextEepromStructure (
+ IN UINT8 LibraryIndex,
+ IN OUT UINT32 *Index,
+ IN OUT UINT8 **Buffer,
+ IN OUT UINT32 *Size
+ );
+
+UINT8
+EFIAPI
+GetValidEepromLibrary (
+ IN BOOLEAN CopyToMemory,
+ IN BOOLEAN MemoryInitialized
+ );
+
+BOOLEAN
+EFIAPI
+InPeiPhase (VOID);
+
+EFI_STATUS
+EFIAPI
+ValidateEeprom (
+ IN UINT8 LibraryIndex
+ );
+
+//
+// Desc: Registers the raw data libraries
+// Variables: None
+// Return: EFI_SUCCESS
+//
+EFI_STATUS
+EFIAPI
+EepromInitConstructor (VOID);
+
+#endif // _EEPROM_LIB_
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/ReadMe.txt b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/ReadMe.txt
new file mode 100644
index 0000000000..5179b97e3d
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/ReadMe.txt
@@ -0,0 +1,62 @@
+## @file
+# 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.
+#
+##
+
+==========================================================================================
+ EEPROM PCDs
+==========================================================================================
+[PcdsFixedAtBuild]
+ ## I2C bus the master EEPROM is hanging on
+ gPlatformModuleTokenSpaceGuid.PcdEepromBus|0x06|UINT8|0xEEEE2000
+ ## 7-bit address of the master EEPROM
+ gPlatformModuleTokenSpaceGuid.PcdEepromAddress|0x53|UINT8|0xEEEE2001
+ ## Priority order of EEPROM data libraries
+ ## 00 - Null; 01 - EEPROM; 02 - FV; 03 - Memory; FF - End of list
+ ## Memory should be first
+ gPlatformModuleTokenSpaceGuid.PcdEepromAutoPriority|{0x03, 0x01, 0x02, 0x00, 0xFF}|VOID*|0xEEEE2002
+ ## Public key file GUID - 5D8A38A3-FBBD-4077-8105-11170C2AF54D
+ gPlatformModuleTokenSpaceGuid.PcdEepromPublicKeyFile|{0xA3, 0x38, 0x8A, 0x5D, 0xBD, 0xFB, 0x77, 0x40, 0x81, 0x05, 0x11, 0x17, 0x0C, 0x2A, 0xF5, 0x4D}|VOID*|0xEEEE2003
+ ## FV EEPROM Image file GUID - BFBD3DAC-01EB-4FEB-A9DE-BCC9D1BA5531
+ gPlatformModuleTokenSpaceGuid.PcdEepromFvImageFile|{0xAC, 0x3D, 0xBD, 0xBF, 0xEB, 0x01, 0xEB, 0x4F, 0xA9, 0xDE, 0xBC, 0xC9, 0xD1, 0xBA, 0x55, 0x31}|VOID*|0xEEEE2004
+
+[PcdsDynamic, PcdsDynamicEx]
+ ## Used to store the EEPROM memory buffer pointer
+ gPlatformModuleTokenSpaceGuid.PcdEepromMemoryPointer|0|UINT64|0xEEEE0000
+ ## Used to store the EEPROM memory buffer size
+ gPlatformModuleTokenSpaceGuid.PcdEepromMemorySize|0|UINT32|0xEEEE0001
+ ## Used to store the EEPROM data library valid flags
+ gPlatformModuleTokenSpaceGuid.PcdEepromLibraryValid|{0x00, 0x00, 0x00, 0x00}|VOID*|0xEEEE0002
+ ## Flag to indicate that a HOB exists with EEPROM_MEMORY data
+ gPlatformModuleTokenSpaceGuid.PcdEepromMemoryHobPresent|FALSE|BOOLEAN|0xEEEE0003
+ ## Pointer to the Part head link
+ gPlatformModuleTokenSpaceGuid.PcdEepromPartsHeadLink|0|UINT64|0xEEEE0004
+ ## Pointer to the Parts table
+ gPlatformModuleTokenSpaceGuid.PcdEepromParts|0|UINT64|0xEEEE0005
+ ## Flag to tell if EEPROM Map is in memory
+ gPlatformModuleTokenSpaceGuid.PcdEepromInMemoryFlag|0|BOOLEAN|0xEEEE0006
+ ## Flag to tell if EEPROM Map is in HOB
+ gPlatformModuleTokenSpaceGuid.PcdEepromMapHobValid|0|BOOLEAN|0xEEEE0007
+
+
+==========================================================================================
+ EEPROM GUIDs
+==========================================================================================
+[Guids]
+ # GUID for EEPROM variables - {EE96CA33-5F59-4594-9869-07F79AA3C06F}
+ gEepromVariableGuid = { 0xEE96CA33, 0x5F59, 0x4594, { 0x98, 0x69, 0x07, 0xF7, 0x9A, 0xA3, 0xC0, 0x6F }}
+
+
+==========================================================================================
+ Generating EEPROM binary
+==========================================================================================
+ Use the GenerateBinary.py script as a guide on how to create the EEPROM binary.
+
--
2.14.1.windows.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2018-07-23 2:39 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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 ` [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
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox