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.120; helo=mga04.intel.com; envelope-from=mang.guo@intel.com; receiver=edk2-devel@lists.01.org Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) (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 83D8820957460 for ; Wed, 28 Mar 2018 00:04:34 -0700 (PDT) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 28 Mar 2018 00:11:10 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.48,370,1517904000"; d="scan'208";a="41336533" Received: from fmsmsx105.amr.corp.intel.com ([10.18.124.203]) by fmsmga004.fm.intel.com with ESMTP; 28 Mar 2018 00:11:10 -0700 Received: from fmsmsx115.amr.corp.intel.com (10.18.116.19) by FMSMSX105.amr.corp.intel.com (10.18.124.203) with Microsoft SMTP Server (TLS) id 14.3.319.2; Wed, 28 Mar 2018 00:11:10 -0700 Received: from shsmsx151.ccr.corp.intel.com (10.239.6.50) by fmsmsx115.amr.corp.intel.com (10.18.116.19) with Microsoft SMTP Server (TLS) id 14.3.319.2; Wed, 28 Mar 2018 00:11:09 -0700 Received: from shsmsx103.ccr.corp.intel.com ([169.254.4.235]) by SHSMSX151.ccr.corp.intel.com ([169.254.3.108]) with mapi id 14.03.0319.002; Wed, 28 Mar 2018 15:11:07 +0800 From: "Guo, Mang" To: "Kinney, Michael D" , "edk2-devel@lists.01.org" CC: "Wei, David" , "Yao, Jiewen" Thread-Topic: [Patch 5/5] Vlv2TbltDevicePkg: Sync FLASH libraries from UDK2017 branch Thread-Index: AQHTxlZW6kTn0B6FVkGwzlk71/ofeKPlOyqw Date: Wed, 28 Mar 2018 07:11:07 +0000 Message-ID: <22D2C85ED001C54AA20BFE3B0E4751D1525CE473@SHSMSX103.ccr.corp.intel.com> References: <20180328053330.13272-1-michael.d.kinney@intel.com> <20180328053330.13272-6-michael.d.kinney@intel.com> In-Reply-To: <20180328053330.13272-6-michael.d.kinney@intel.com> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.239.127.40] MIME-Version: 1.0 Subject: Re: [Patch 5/5] Vlv2TbltDevicePkg: Sync FLASH libraries from UDK2017 branch X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 28 Mar 2018 07:04:35 -0000 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Reviewed-by: Guo Mang -----Original Message----- From: Kinney, Michael D=20 Sent: Wednesday, March 28, 2018 1:34 PM To: edk2-devel@lists.01.org Cc: Wei, David; Guo, Mang; Yao, Jiewen; Kinney, Michael D Subject: [Patch 5/5] Vlv2TbltDevicePkg: Sync FLASH libraries from UDK2017 b= ranch https://bugzilla.tianocore.org/show_bug.cgi?id=3D911 Update Minnow Max FLASH libraries to match libraries in the UDK2017 develop= ment branch in edk2-platforms. https://github.com/tianocore/edk2-platforms/tree/devel-MinnowBoardMax-UDK20= 17 Cc: David Wei Cc: Mang Guo Cc: Jiewen Yao Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Michael D Kinney --- .../PlatformFlashAccessLib.c | 491 +++++++++++++++++= +++- .../PlatformFlashAccessLib.inf | 19 +- .../Library/FlashDeviceLib/FlashDeviceLib.c | 158 ++++++- .../Library/FlashDeviceLib/FlashDeviceLib.inf | 6 +- .../Library/FlashDeviceLib/SpiChipDefinitions.h | 1 + 5 files changed, 639 insertions(+), 36 deletions(-) diff --git a/Vlv2TbltDevicePkg/Feature/Capsule/Library/PlatformFlashAccessL= ib/PlatformFlashAccessLib.c b/Vlv2TbltDevicePkg/Feature/Capsule/Library/Pla= tformFlashAccessLib/PlatformFlashAccessLib.c index f3cb31daaa..9162e025ed 100644 --- a/Vlv2TbltDevicePkg/Feature/Capsule/Library/PlatformFlashAccessLib/Plat= formFlashAccessLib.c +++ b/Vlv2TbltDevicePkg/Feature/Capsule/Library/PlatformFlashAccessLib/P +++ latformFlashAccessLib.c @@ -1,7 +1,7 @@ /** @file Platform Flash Access library. =20 - Copyright (c) 2016, Intel Corporation. All rights reserved.
+ Copyright (c) 2017, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BS= D License which accompanies this distribution. The full text of the license may b= e found at @@ -11,6 +11,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMP= LIED. =20 **/ +#include =20 #include =20 @@ -19,14 +20,366 @@ #include #include #include -#include +//#include #include +#include +#include #include "PchAccess.h" +#include +#include +#include +#include =20 -#define SECTOR_SIZE_64KB 0x10000 // Common 64kBytes sector size -#define ALINGED_SIZE SECTOR_SIZE_64KB +//#define SECTOR_SIZE_64KB 0x10000 // Common 64kBytes sector size +//#define ALINGED_SIZE SECTOR_SIZE_64KB + +#define BLOCK_SIZE 0x1000 +#define ALINGED_SIZE BLOCK_SIZE + +#define R_PCH_LPC_BIOS_CNTL 0xDC +#define B_PCH_LPC_BIOS_CNTL_SMM_BWP 0x20 ///< SMM= BIOS write protect disable + +// +// Prefix Opcode Index on the host SPI controller // typedef enum { + SPI_WREN, // Prefix Opcode 0: Write Enable + SPI_EWSR, // Prefix Opcode 1: Enable Write Status Register +} PREFIX_OPCODE_INDEX; +// +// Opcode Menu Index on the host SPI controller // typedef enum { + SPI_READ_ID, // Opcode 0: READ ID, Read cycle with address + SPI_READ, // Opcode 1: READ, Read cycle with address + SPI_RDSR, // Opcode 2: Read Status Register, No address + SPI_WRDI_SFDP, // Opcode 3: Write Disable or Discovery Parameters, = No address + SPI_SERASE, // Opcode 4: Sector Erase (4KB), Write cycle with ad= dress + SPI_BERASE, // Opcode 5: Block Erase (32KB), Write cycle with ad= dress + SPI_PROG, // Opcode 6: Byte Program, Write cycle with address + SPI_WRSR, // Opcode 7: Write Status Register, No address +} SPI_OPCODE_INDEX; =20 STATIC EFI_PHYSICAL_ADDRESS mInternalFdAddress; =20 +EFI_SPI_PROTOCOL *mSpiProtocol; + +/** + Read NumBytes bytes of data from the address specified by + PAddress into Buffer. + + @param[in] Address The starting physical address of the read. + @param[in,out] NumBytes On input, the number of bytes to read. On = output, the number + of bytes actually read. + @param[out] Buffer The destination data buffer for the read. + + @retval EFI_SUCCESS Opertion is successful. + @retval EFI_DEVICE_ERROR If there is any device errors. + +**/ +EFI_STATUS +EFIAPI +SpiFlashRead ( + IN UINTN Address, + IN OUT UINT32 *NumBytes, + OUT UINT8 *Buffer + ) +{ + EFI_STATUS Status =3D EFI_SUCCESS; + UINTN Offset =3D 0; + + ASSERT ((NumBytes !=3D NULL) && (Buffer !=3D NULL)); + + + //if (Address >=3D (UINTN)PcdGet32 (PcdGbeRomBase) && Address < (UINTN)P= cdGet32 (PcdPDRRomBase)) { + Offset =3D Address - (UINTN)PcdGet32 (PcdFlashChipBase); + + Status =3D mSpiProtocol->Execute ( + mSpiProtocol, + 1, //SPI_READ, + 0, //SPI_WREN, + TRUE, + TRUE, + FALSE, + Offset, + BLOCK_SIZE, + Buffer, + EnumSpiRegionAll + ); + return Status; +} + +/** + Write NumBytes bytes of data from Buffer to the address specified by + PAddresss. + + @param[in] Address The starting physical address of the wri= te. + @param[in,out] NumBytes On input, the number of bytes to write. = On output, + the actual number of bytes written. + @param[in] Buffer The source data buffer for the write. + + @retval EFI_SUCCESS Opertion is successful. + @retval EFI_DEVICE_ERROR If there is any device errors. + +**/ +EFI_STATUS +EFIAPI +SpiFlashWrite ( + IN UINTN Address, + IN OUT UINT32 *NumBytes, + IN UINT8 *Buffer + ) +{ + EFI_STATUS Status; + UINTN Offset; + UINT32 Length; + UINT32 RemainingBytes; + + ASSERT ((NumBytes !=3D NULL) && (Buffer !=3D NULL)); ASSERT (Address >= =3D=20 + (UINTN)PcdGet32 (PcdFlashChipBase)); + + Offset =3D Address - (UINTN)PcdGet32 (PcdFlashChipBase); + + ASSERT ((*NumBytes + Offset) <=3D (UINTN)PcdGet32 (PcdFlashChipSize)); + + Status =3D EFI_SUCCESS; + RemainingBytes =3D *NumBytes; + + while (RemainingBytes > 0) { + if (RemainingBytes > SIZE_4KB) { + Length =3D SIZE_4KB; + } else { + Length =3D RemainingBytes; + } + Status =3D mSpiProtocol->Execute ( + mSpiProtocol, + SPI_PROG, + SPI_WREN, + TRUE, + TRUE, + TRUE, + (UINT32) Offset, + Length, + Buffer, + EnumSpiRegionAll + ); + if (EFI_ERROR (Status)) { + break; + } + RemainingBytes -=3D Length; + Offset +=3D Length; + Buffer +=3D Length; + } + + // + // Actual number of bytes written + // + *NumBytes -=3D RemainingBytes; + + return Status; +} + + +EFI_STATUS +InternalReadBlock ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + OUT VOID *ReadBuffer + ) +{ + EFI_STATUS Status; + UINT32 BlockSize; + + BlockSize =3D BLOCK_SIZE; + + Status =3D SpiFlashRead ((UINTN) BaseAddress, &BlockSize, ReadBuffer); + + return Status; +} + +/** + Erase the block starting at Address. + + @param[in] Address The starting physical address of the block t= o be erased. + This library assume that caller garantee tha= t the PAddress + is at the starting address of this block. + @param[in] NumBytes On input, the number of bytes of the logical= block to be erased. + On output, the actual number of bytes erased= . + + @retval EFI_SUCCESS. Opertion is successful. + @retval EFI_DEVICE_ERROR If there is any device errors. + +**/ +EFI_STATUS +EFIAPI +SpiFlashBlockErase ( + IN UINTN Address, + IN UINTN *NumBytes + ) +{ + EFI_STATUS Status; + UINTN Offset; + UINTN RemainingBytes; + + ASSERT (NumBytes !=3D NULL); + ASSERT (Address >=3D (UINTN)PcdGet32 (PcdFlashChipBase)); + + Offset =3D Address - (UINTN)PcdGet32 (PcdFlashChipBase); + + ASSERT ((*NumBytes % SIZE_4KB) =3D=3D 0); ASSERT ((*NumBytes + Offset)= =20 + <=3D (UINTN)PcdGet32 (PcdFlashChipSize)); + + Status =3D EFI_SUCCESS; + RemainingBytes =3D *NumBytes; + + // + // To adjust the Offset with Bios/Gbe + // +// if (Address >=3D (UINTN)PcdGet32 (PcdFlashChipBase)) { +// Offset =3D Address - (UINTN)PcdGet32 (PcdFlashChipBase); + + while (RemainingBytes > 0) { + Status =3D mSpiProtocol->Execute ( + mSpiProtocol, + SPI_SERASE, + SPI_WREN, + FALSE, + TRUE, + FALSE, + (UINT32) Offset, + 0, + NULL, + EnumSpiRegionAll + ); + if (EFI_ERROR (Status)) { + break; + } + RemainingBytes -=3D SIZE_4KB; + Offset +=3D SIZE_4KB; + } +// } + + // + // Actual number of bytes erased + // + *NumBytes -=3D RemainingBytes; + + return Status; +} + +/** + +Routine Description: + + Erase the whole block. + +Arguments: + + BaseAddress - Base address of the block to be erased. + +Returns: + + EFI_SUCCESS - The command completed successfully. + Other - Device error or wirte-locked, operation failed. + +**/ +EFI_STATUS +InternalEraseBlock ( + IN EFI_PHYSICAL_ADDRESS BaseAddress + ) +{ + EFI_STATUS Status; + UINTN NumBytes; + + NumBytes =3D BLOCK_SIZE; + + Status =3D SpiFlashBlockErase ((UINTN) BaseAddress, &NumBytes); + + return Status; +} + +EFI_STATUS +InternalCompareBlock ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT8 *Buffer + ) +{ + EFI_STATUS Status; + VOID *CompareBuffer; + UINT32 NumBytes; + INTN CompareResult; + + NumBytes =3D BLOCK_SIZE; + CompareBuffer =3D AllocatePool (NumBytes); if (CompareBuffer =3D=3D NUL= L)=20 + { + Status =3D EFI_OUT_OF_RESOURCES; + goto Done; + } + + Status =3D SpiFlashRead ((UINTN) BaseAddress, &NumBytes,=20 + CompareBuffer); if (EFI_ERROR (Status)) { + goto Done; + } + CompareResult =3D CompareMem (CompareBuffer, Buffer, BLOCK_SIZE); if=20 + (CompareResult !=3D 0) { + Status =3D EFI_VOLUME_CORRUPTED; + } + +Done: + if (CompareBuffer !=3D NULL) { + FreePool (CompareBuffer); + } + + return Status; +} + +/** + +Routine Description: + + Write a block of data. + +Arguments: + + BaseAddress - Base address of the block. + Buffer - Data buffer. + BufferSize - Size of the buffer. + +Returns: + + EFI_SUCCESS - The command completed successfully. + EFI_INVALID_PARAMETER - Invalid parameter, can not proceed. + Other - Device error or wirte-locked, operation failed. + +**/ +EFI_STATUS +InternalWriteBlock ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT8 *Buffer, + IN UINT32 BufferSize + ) +{ + EFI_STATUS Status; + + Status =3D SpiFlashWrite ((UINTN) BaseAddress, &BufferSize, Buffer); + + if (EFI_ERROR (Status)) { + DEBUG((DEBUG_ERROR, "\nFlash write error.")); + return Status; + } + + WriteBackInvalidateDataCacheRange ((VOID *) (UINTN) BaseAddress,=20 + BLOCK_SIZE); + + Status =3D InternalCompareBlock (BaseAddress, Buffer); if (EFI_ERROR=20 + (Status)) { + DEBUG((DEBUG_ERROR, "\nError when writing to BaseAddress %x with=20 + different at offset %x.", BaseAddress, Status)); } else { + DEBUG((DEBUG_INFO, "\nVerified data written to Block at %x is=20 + correct.", BaseAddress)); } + + return Status; + +} + /** Perform flash write opreation. =20 @@ -51,36 +404,122 @@ PerformFlashWrite ( IN UINTN Length ) { - EFI_STATUS Status; + EFI_STATUS Status =3D EFI_SUCCESS; + UINTN Index; + EFI_PHYSICAL_ADDRESS Address; + UINTN CountOfBlocks; + EFI_TPL OldTpl; + BOOLEAN FlashError; + UINT8 *Buf; + UINTN LpcBaseAddress; + UINT8 Data8Or; + UINT8 Data8And; + UINT8 BiosCntl; =20 - DEBUG((DEBUG_INFO, "PerformFlashWrite - 0x%x(%x) - 0x%x\n", (UINTN)Flash= Address, (UINTN)FlashAddressType, Length)); + Index =3D 0; + Address =3D 0; + CountOfBlocks =3D 0; + FlashError =3D FALSE; + Buf =3D Buffer; + + DEBUG((DEBUG_INFO | DEBUG_ERROR, "PerformFlashWrite - 0x%x(%x) -=20 + 0x%x\n", (UINTN)FlashAddress, (UINTN)FlashAddressType, Length)); if (FlashAddressType =3D=3D FlashAddressTypeRelativeAddress) { FlashAddress =3D FlashAddress + mInternalFdAddress; } =20 - DEBUG((DEBUG_INFO, " - 0x%x(%x) - 0x%x\n", (UINTN)Flash= Address, (UINTN)FlashAddressType, Length)); - LibFvbFlashDeviceBlockLock((UINTN)FlashAddress, Length, FALSE); + CountOfBlocks =3D (UINTN) (Length / BLOCK_SIZE); Address =3D=20 + FlashAddress; =20 + LpcBaseAddress =3D MmPciAddress (0, + DEFAULT_PCI_BUS_NUMBER_PCH, + PCI_DEVICE_NUMBER_PCH_LPC, + PCI_FUNCTION_NUMBER_PCH_LPC, + 0 + ); + BiosCntl =3D MmioRead8 (LpcBaseAddress + R_PCH_LPC_BIOS_CNTL); if=20 + ((BiosCntl & B_PCH_LPC_BIOS_CNTL_SMM_BWP) =3D=3D B_PCH_LPC_BIOS_CNTL_SMM_= BWP) { + /// + /// Clear SMM_BWP bit (D31:F0:RegDCh[5]) + /// + Data8And =3D (UINT8) ~B_PCH_LPC_BIOS_CNTL_SMM_BWP; + Data8Or =3D 0x00; + + MmioAndThenOr8 ( + LpcBaseAddress + R_PCH_LPC_BIOS_CNTL, + Data8And, + Data8Or + ); + DEBUG((DEBUG_INFO, "PerformFlashWrite Clear SMM_BWP bit\n")); } + + // + // Raise TPL to TPL_NOTIFY to block any event handler, + // while still allowing RaiseTPL(TPL_NOTIFY) within + // output driver during Print() // - // Erase & Write - // - Status =3D LibFvbFlashDeviceBlockErase((UINTN)FlashAddress, Length); - ASSERT_EFI_ERROR(Status); + OldTpl =3D gBS->RaiseTPL (TPL_NOTIFY); + for (Index =3D 0; Index < CountOfBlocks; Index++) { + // + // Handle block based on address and contents. + // + if (!EFI_ERROR (InternalCompareBlock (Address, Buf))) { + DEBUG((DEBUG_INFO, "Skipping block at 0x%lx (already programmed)\n= ", Address)); + } else { + // + // Display a dot for each block being updated. + // + Print (L"."); + + // + // Make updating process uninterruptable, + // so that the flash memory area is not accessed by other entities + // which may interfere with the updating process + // + Status =3D InternalEraseBlock (Address); if (EFI_ERROR(Status)) { - LibFvbFlashDeviceBlockLock((UINTN)FlashAddress, Length, TRUE); - DEBUG((DEBUG_ERROR, "Flash Erase error\n")); - return Status; + gBS->RestoreTPL (OldTpl); + FlashError =3D TRUE; + goto Done; } - - Status =3D LibFvbFlashDeviceWrite((UINTN)FlashAddress, &Length, Buffer); - ASSERT_EFI_ERROR(Status); + Status =3D InternalWriteBlock ( + Address, + Buf, + (UINT32)(Length > BLOCK_SIZE ? BLOCK_SIZE : Length) + ); if (EFI_ERROR(Status)) { - LibFvbFlashDeviceBlockLock((UINTN)FlashAddress, Length, TRUE); - DEBUG((DEBUG_ERROR, "Flash write error\n")); - return Status; + gBS->RestoreTPL (OldTpl); + FlashError =3D TRUE; + goto Done; + } } =20 - LibFvbFlashDeviceBlockLock((UINTN)FlashAddress, Length, TRUE); + // + // Move to next block to update. + // + Address +=3D BLOCK_SIZE; + Buf +=3D BLOCK_SIZE; + if (Length > BLOCK_SIZE) { + Length -=3D BLOCK_SIZE; + } else { + Length =3D 0; + } + } + gBS->RestoreTPL (OldTpl); + + Done: + if ((BiosCntl & B_PCH_LPC_BIOS_CNTL_SMM_BWP) =3D=3D B_PCH_LPC_BIOS_CNTL_= SMM_BWP) { + // + // Restore original control setting + // + MmioWrite8 (LpcBaseAddress + R_PCH_LPC_BIOS_CNTL, BiosCntl); + } + + // + // Print flash update failure message if error detected. + // + if (FlashError) { + Print (L"No %r\n", Status); + } =20 return EFI_SUCCESS; } @@ -183,8 +622,16 @@ PerformFlashAccessLibConstructor ( VOID ) { + EFI_STATUS Status; mInternalFdAddress =3D (EFI_PHYSICAL_ADDRESS)(UINTN)PcdGet32(PcdFlashAre= aBaseAddress); DEBUG((DEBUG_INFO, "PcdFlashAreaBaseAddress - 0x%x\n", mInternalFdAddres= s)); =20 + Status =3D gBS->LocateProtocol ( + &gEfiSpiProtocolGuid, + NULL, + (VOID **) &mSpiProtocol + ); + ASSERT_EFI_ERROR(Status); + return EFI_SUCCESS; } diff --git a/Vlv2TbltDevicePkg/Feature/Capsule/Library/PlatformFlashAccessL= ib/PlatformFlashAccessLib.inf b/Vlv2TbltDevicePkg/Feature/Capsule/Library/P= latformFlashAccessLib/PlatformFlashAccessLib.inf index 17ab38e27f..fbbdb91b64 100644 --- a/Vlv2TbltDevicePkg/Feature/Capsule/Library/PlatformFlashAccessLib/Plat= formFlashAccessLib.inf +++ b/Vlv2TbltDevicePkg/Feature/Capsule/Library/PlatformFlashAccessLib/P +++ latformFlashAccessLib.inf @@ -1,7 +1,7 @@ ## @file # Platform Flash Access library. # -# Copyright (c) 2016, Intel Corporation. All rights reserved.
+# Copyright (c) 2017, Intel Corporation. All rights reserved.
# This program and the accompanying materials # are licensed and made a= vailable under the terms and conditions of the BSD License # which accomp= anies this distribution. The full text of the license may be found at @@ -= 36,13 +36,26 @@ [Packages] MdeModulePkg/MdeModulePkg.dec SignedCapsulePkg/SignedCapsulePkg.dec Vlv2TbltDevicePkg/PlatformPkg.dec + Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec =20 [LibraryClasses] BaseMemoryLib + IoLib PcdLib DebugLib - FlashDeviceLib +# FlashDeviceLib MemoryAllocationLib + CacheMaintenanceLib + +[Guids] + gEdkiiSystemFmpCapsuleConfigFileGuid ## SOMETIMES_CONSUMES ## G= UID + +[Protocols] + gEfiSpiProtocolGuid ## CONSUMES =20 [Pcd] - gPlatformModuleTokenSpaceGuid.PcdFlashAreaBaseAddress + gPlatformModuleTokenSpaceGuid.PcdFlashAreaBaseAddress ## SOMETIMES_CONS= UMES + gPlatformModuleTokenSpaceGuid.PcdFlashChipBase ## SOMETIMES_CONS= UMES + gPlatformModuleTokenSpaceGuid.PcdFlashChipSize ## SOMETIMES_CONS= UMES + gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress ## SOMETIMES_CONS= UMES + diff --git a/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLib.c b/Vl= v2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLib.c index 8e6e5b4728..392ad1c14b 100644 --- a/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLib.c +++ b/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLib.c @@ -19,13 +19,14 @@ #include #include #include +#include +#include #include +#include +#include #include -#include +#include "SpiChipDefinitions.h" =20 -#define FLASH_SIZE 0x400000 - -#define FLASH_DEVICE_BASE_ADDRESS (0xFFFFFFFF-FLASH_SIZE+1) UINTN FlashDe= viceBase =3D FLASH_DEVICE_BASE_ADDRESS; =20 EFI_SPI_PROTOCOL *mSpiProtocol =3D NULL; @@ -77,11 +78,11 @@ SpiFlashBlockErase ( UINT32 SpiAddress; =20 SpiAddress =3D (UINT32)(UINTN)(BaseAddress) - (UINT32)FlashDeviceBase; - SectorSize =3D SECTOR_SIZE_64KB; + SectorSize =3D SECTOR_SIZE_4KB; while ( (NumBytes > 0) && (NumBytes <=3D MAX_FWH_SIZE) ) { Status =3D mSpiProtocol->Execute ( mSpiProtocol, - SPI_BERASE, + SPI_SERASE, SPI_WREN, FALSE, TRUE, @@ -319,3 +320,148 @@ LibFvbFlashDeviceBlockLock ( return Status; } =20 +VOID +EFIAPI +LibFvbFlashDeviceVirtualAddressChangeNotifyEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + gRT->ConvertPointer (0, (VOID **) &mSpiProtocol); + gRT->ConvertPointer (0, (VOID **) &FlashDeviceBase); } + + +/** + The library constructuor. + + The function does the necessary initialization work for this library =20 + instance. Please put all initialization works in it. + + @param[in] ImageHandle The firmware allocated handle for the UEFI= image. + @param[in] SystemTable A pointer to the EFI system table. + + @retval EFI_SUCCESS The function always return EFI_SUCCESS for= now. + It will ASSERT on error for debug version. + @retval EFI_ERROR Please reference LocateProtocol for error = code details. + +**/ +EFI_STATUS +EFIAPI +LibFvbFlashDeviceSupportInit ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_EVENT Event; + UINT8 SfId[3]; + UINT8 FlashIndex; + UINT8 SpiReadError; + UINT8 SpiNotMatchError; + EFI_SMM_BASE2_PROTOCOL *SmmBase; + BOOLEAN InSmm; + + SpiReadError =3D 0x00; + SpiNotMatchError =3D 0x00; + + InSmm =3D FALSE; + Status =3D gBS->LocateProtocol ( + &gEfiSmmBase2ProtocolGuid, + NULL, + (void **)&SmmBase + ); + if (!EFI_ERROR(Status)) { + Status =3D SmmBase->InSmm(SmmBase, &InSmm); + if (EFI_ERROR(Status)) { + InSmm =3D FALSE; + } + } + + if (!InSmm) { + Status =3D gBS->LocateProtocol ( + &gEfiSpiProtocolGuid, + NULL, + (VOID **)&mSpiProtocol + ); + ASSERT_EFI_ERROR (Status); + + Status =3D gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + LibFvbFlashDeviceVirtualAddressChangeNotifyEvent, + NULL, + &gEfiEventVirtualAddressChangeGuid, + &Event + ); + ASSERT_EFI_ERROR (Status); + } else { + Status =3D gBS->LocateProtocol ( + &gEfiSmmSpiProtocolGuid, + NULL, + (VOID **)&mSpiProtocol + ); + ASSERT_EFI_ERROR (Status); + } + + + for (FlashIndex =3D EnumSpiFlashW25Q64; FlashIndex < EnumSpiFlashMax; Fl= ashIndex++) { + Status =3D mSpiProtocol->Init (mSpiProtocol, &(mInitTable[FlashIndex])= ); + if (!EFI_ERROR (Status)) { + // + // Read Vendor/Device IDs to check if the driver supports the Serial= Flash device. + // + Status =3D mSpiProtocol->Execute ( + mSpiProtocol, + SPI_READ_ID, + SPI_WREN, + TRUE, + FALSE, + FALSE, + 0, + 3, + SfId, + EnumSpiRegionAll + ); + if (!EFI_ERROR (Status)) { + if ((SfId[0] =3D=3D mInitTable[FlashIndex].VendorId) && + (SfId[1] =3D=3D mInitTable[FlashIndex].DeviceId0) && + (SfId[2] =3D=3D mInitTable[FlashIndex].DeviceId1)) { + // + // Found a matching SPI device, FlashIndex now contains flash = device. + // + DEBUG ((DEBUG_ERROR, "OK - Found SPI Flash Type in SPI Flash D= river, Device Type ID 0 =3D 0x%02x!\n", mInitTable[FlashIndex].DeviceId0)); + DEBUG ((DEBUG_ERROR, "Device Type ID 1 =3D 0x%02x!\n",=20 + mInitTable[FlashIndex].DeviceId1)); + + if (mInitTable[FlashIndex].BiosStartOffset =3D=3D (UINTN) (-1)= ) { + DEBUG ((DEBUG_ERROR, "ERROR - The size of BIOS image is bigg= er than SPI Flash device!\n")); + CpuDeadLoop (); + } + break; + } else { + SpiNotMatchError++; + } + } else { + SpiReadError++; + } + } + } + + DEBUG ((DEBUG_ERROR, "SPI flash chip VID =3D 0x%X, DID0 =3D 0x%X, DID1 = =3D=20 + 0x%X\n", SfId[0], SfId[1], SfId[2])); + + if (FlashIndex < EnumSpiFlashMax) { + return EFI_SUCCESS; + } else { + if (SpiReadError !=3D 0) { + DEBUG ((DEBUG_ERROR, "ERROR - SPI Read ID execution failed! Error Co= unt =3D %d\n", SpiReadError)); + } + else { + if (SpiNotMatchError !=3D 0) { + DEBUG ((DEBUG_ERROR, "ERROR - No supported SPI flash chip found! E= rror Count =3D %d\n", SpiNotMatchError)); + DEBUG ((DEBUG_ERROR, "SPI flash chip VID =3D 0x%X, DID0 =3D 0x%X, = DID1 =3D 0x%X\n", SfId[0], SfId[1], SfId[2])); + } + } + return EFI_UNSUPPORTED; + } +} + diff --git a/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLib.inf b/= Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLib.inf index 955b2479f6..3331432b68 100644 --- a/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLib.inf +++ b/Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLib.inf @@ -16,7 +16,7 @@ =20 [Defines] INF_VERSION =3D 0x00010005 - BASE_NAME =3D FlashDeviceLibRuntimeSmm + BASE_NAME =3D FlashDeviceLib FILE_GUID =3D E38A1C3C-928C-4bf7-B6C1-7F0EF163FAA5 MODULE_TYPE =3D DXE_DRIVER VERSION_STRING =3D 1.0 @@ -32,7 +32,6 @@ [Defines] =20 [Sources] FlashDeviceLib.c - FlashDeviceLibDxeRuntimeSmm.c =20 =20 [Packages] @@ -44,9 +43,6 @@ [Packages] [LibraryClasses] DebugLib =20 -[Guids] - gEfiEventVirtualAddressChangeGuid - [Protocols] gEfiSpiProtocolGuid gEfiSmmSpiProtocolGuid diff --git a/Vlv2TbltDevicePkg/Library/FlashDeviceLib/SpiChipDefinitions.h = b/Vlv2TbltDevicePkg/Library/FlashDeviceLib/SpiChipDefinitions.h index fdf742c1ba..954aadc174 100644 --- a/Vlv2TbltDevicePkg/Library/FlashDeviceLib/SpiChipDefinitions.h +++ b/Vlv2TbltDevicePkg/Library/FlashDeviceLib/SpiChipDefinitions.h @@ -17,6 +17,7 @@ #include =20 #define FLASH_SIZE 0x400000 +#define FLASH_DEVICE_BASE_ADDRESS (0xFFFFFFFF-FLASH_SIZE+1) =20 // // Serial Flash device initialization data table provided to the -- 2.14.2.windows.3