From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=192.55.52.93; helo=mga11.intel.com; envelope-from=david.wei@intel.com; receiver=edk2-devel@lists.01.org Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id DEEF9210C0CED for ; Sun, 22 Jul 2018 19:39:57 -0700 (PDT) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 22 Jul 2018 19:39:57 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.51,391,1526367600"; d="scan'208";a="58607323" Received: from unknown (HELO zwei4-MOBL1.ccr.corp.intel.com) ([10.239.193.109]) by orsmga007.jf.intel.com with ESMTP; 22 Jul 2018 19:39:50 -0700 From: zwei4 To: edk2-devel@lists.01.org Cc: David Wei , Kelly Steele , Mike Wu , Mang Guo Date: Mon, 23 Jul 2018 10:39:17 +0800 Message-Id: <20180723023919.19796-3-david.wei@intel.com> X-Mailer: git-send-email 2.14.1.windows.1 In-Reply-To: <20180723023919.19796-1-david.wei@intel.com> References: <20180723023919.19796-1-david.wei@intel.com> Subject: [Patch][edk2-platforms/devel-IntelAtomProcessorE3900 3/5] Library producing EEPROM raw data functionality. X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.27 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 23 Jul 2018 02:39:58 -0000 Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: David Wei CC: Kelly Steele CC: Mike Wu CC: Mang Guo --- .../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.
+ + 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.
+ + 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 + +#include +#include +#include +#include +#include +#include + +#include +#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.
+ + 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 +#include + +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.
+ + 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 +#include + +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.
+ + 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.
+ + 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 + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +// +// 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.
+ + 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.
+ + 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 + +#include +#include +#include +#include +#include + +//// +//// 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.
+# +# 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.
+# +# 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.
+# +# 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.
+ + 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.
+ + 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 + +#include +#include +#include +#include + +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.
+ + 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 +#include +#include +#include + +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.
+ + 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 +#include + +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.
+ + 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.
+ + 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 + +#include + +#include +#include +#include +#include + +//// +//// 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.
+ + 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 +#include + +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.
+ + 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 +#include + +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.
+ + 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 + +// +// 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.
+ + 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 +#include +#include + +// +// 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.
+ + 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.
+ + 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 + +#include +#include + +#endif // _EEPROM_DATA_NULL_LIB_ -- 2.14.1.windows.1