From: Jan Dąbroś jsd@semihalf.com
sf command uses MARVELL_SPI_FLASH_PROTOCOL and MARVELL_SPI_MASTER_PROTOCOL. It allows read/write/erase/update operations on SPI flash.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jan Dabros jsd@semihalf.com Signed-off-by: Marcin Wojtas mw@semihalf.com Reviewed-by: Leif Lindholm leif.lindholm@linaro.org --- Applications/SpiTool/SpiFlashCmd.c | 526 +++++++++++++++++++++++++++++++++++ Applications/SpiTool/SpiFlashCmd.inf | 75 +++++ Applications/SpiTool/SpiFlashCmd.uni | Bin 0 -> 7216 bytes Platforms/Marvell/Marvell.dec | 1 + 4 files changed, 602 insertions(+) create mode 100644 Applications/SpiTool/SpiFlashCmd.c create mode 100644 Applications/SpiTool/SpiFlashCmd.inf create mode 100644 Applications/SpiTool/SpiFlashCmd.uni
diff --git a/Applications/SpiTool/SpiFlashCmd.c b/Applications/SpiTool/SpiFlashCmd.c new file mode 100644 index 0000000..184e3d7 --- /dev/null +++ b/Applications/SpiTool/SpiFlashCmd.c @@ -0,0 +1,526 @@ +/******************************************************************************* +Copyright (C) 2016 Marvell International Ltd. + +Marvell BSD License Option + +If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +* Neither the name of Marvell nor the names of its contributors may be + used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*******************************************************************************/ +#include <Uefi.h> +#include <ShellBase.h> + +#include <Library/BaseLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/DebugLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/ShellCommandLib.h> +#include <Library/ShellLib.h> +#include <Library/UefiLib.h> +#include <Library/UefiBootServicesTableLib.h> +#include <Library/PrintLib.h> +#include <Library/ShellCEntryLib.h> +#include <Library/HiiLib.h> +#include <Library/FileHandleLib.h> + +#include <Protocol/Spi.h> +#include <Protocol/SpiFlash.h> + +MARVELL_SPI_FLASH_PROTOCOL *SpiFlashProtocol; +MARVELL_SPI_MASTER_PROTOCOL *SpiMasterProtocol; + +CONST CHAR16 gShellSpiFlashFileName[] = L"ShellCommand"; +EFI_HANDLE gShellSfHiiHandle = NULL; + +BOOLEAN InitFlag = 1; + +STATIC CONST SHELL_PARAM_ITEM ParamList[] = { + {L"read", TypeFlag}, + {L"readfile", TypeFlag}, + {L"write", TypeFlag}, + {L"writefile", TypeFlag}, + {L"erase", TypeFlag}, + {L"update", TypeFlag}, + {L"updatefile", TypeFlag}, + {L"probe", TypeFlag}, + {L"help", TypeFlag}, + {NULL , TypeMax} + }; + +typedef enum { + PROBE = 1, + READ = 2, + READ_FILE = 4, + WRITE = 8, + WRITE_FILE = 16, + ERASE = 32, + UPDATE = 64, + UPDATE_FILE = 128, +} Flags; + +/** + Return the file name of the help text file if not using HII. + + @return The string pointer to the file name. +**/ +CONST CHAR16* +EFIAPI +ShellCommandGetManFileNameSpiFlash ( + VOID + ) +{ + + return gShellSpiFlashFileName; +} + +VOID +SfUsage ( + VOID + ) +{ + Print (L"\nBasic SPI command\n" + "sf [probe | read | readfile | write | writefile | erase |" + "update | updatefile]" + "[<Address> | <FilePath>] <Offset> <Length>\n\n" + "Length - Number of bytes to send\n" + "Address - Address in RAM to store/load data\n" + "FilePath - Path to file to read/write data from/to\n" + "Offset - Offset from beggining of SPI flash to store/load data\n" + "Examples:\n" + "Check if there is response from SPI flash\n" + " sf probe\n" + "Read 32 bytes from 0xe00000 of SPI flash into RAM at address 0x100000\n" + " sf read 0x100000 0xe00000 32\n" + "Read 0x20 bytes from 0x200000 of SPI flash into RAM at address 0x300000\n" + " sf read 0x300000 0x200000 0x20\n" + "Erase 0x10000 bytes from offset 0x100000 of SPI flash\n" + " sf erase 0x100000 0x100000\n" + "Write 16 bytes from 0x200000 at RAM into SPI flash at address 0x4000000\n" + " sf write 0x200000 0x4000000 16\n" + "Update 100 bytes from 0x100000 at RAM in SPI flash at address 0xe00000\n" + " sf update 0x100000 0xe00000 100\n" + "Read 0x3000 bytes from 0x0 of SPI flash into file fs2:file.bin\n" + " sf readfile fs2:file.bin 0x0 0x3000 \n" + "Update data in SPI flash at 0x3000000 from file Linux.efi\n" + " sf updatefile Linux.efi 0x3000000\n" + ); +} + +STATIC +EFI_STATUS +OpenAndPrepareFile ( + IN CHAR16 *FilePath, + SHELL_FILE_HANDLE *FileHandle + ) +{ + EFI_STATUS Status; + UINT64 OpenMode; + + OpenMode = EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE; + + Status = ShellOpenFileByName (FilePath, FileHandle, OpenMode, 0); + if (EFI_ERROR (Status)) { + Print (L"sf: Cannot open file\n"); + return Status; + } + + Status = FileHandleSetPosition(*FileHandle, 0); + + if (EFI_ERROR(Status)) { + Print (L"sf: Cannot set file position to first byte\n"); + ShellCloseFile (FileHandle); + return Status; + } + + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +FlashProbe ( + IN SPI_DEVICE *Slave + ) +{ + EFI_STATUS Status; + UINT8 IdBuffer[4]; + UINT32 Id, RefId; + + Id = PcdGet32 (PcdSpiFlashId); + + IdBuffer[0] = CMD_READ_ID; + + SpiFlashProtocol->ReadId ( + Slave, + 4, + IdBuffer + ); + + RefId = (IdBuffer[0] << 16) + (IdBuffer[1] << 8) + IdBuffer[2]; + + if (RefId == Id) { + Print (L"sf: Detected supported SPI flash with ID=%3x\n", RefId); + Status = SpiFlashProtocol->Init (SpiFlashProtocol, Slave); + if (EFI_ERROR(Status)) { + Print (L"sf: Cannot initialize flash device\n"); + return SHELL_ABORTED; + } + InitFlag = 0; + return EFI_SUCCESS; + } else if (RefId != 0) { + Print (L"sf: Unsupported SPI flash detected with ID=%2x\n", RefId); + return SHELL_ABORTED; + } + + Print (L"sf: No SPI flash detected"); + return SHELL_ABORTED; +} + +SHELL_STATUS +EFIAPI +ShellCommandRunSpiFlash ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ +EFI_STATUS Status; + SPI_DEVICE *Slave; + LIST_ENTRY *CheckPackage; + EFI_PHYSICAL_ADDRESS Address = 0, Offset = 0; + SHELL_FILE_HANDLE FileHandle = NULL; + UINTN ByteCount, FileSize, I; + UINT8 *Buffer = NULL, *FileBuffer = NULL; + CHAR16 *ProblemParam, *FilePath; + CONST CHAR16 *AddressStr = NULL, *OffsetStr = NULL; + CONST CHAR16 *LengthStr = NULL, *FileStr = NULL; + BOOLEAN AddrFlag = FALSE, LengthFlag = TRUE, FileFlag = FALSE; + UINT8 Flag = 0, CheckFlag = 0; + + Status = gBS->LocateProtocol ( + &gMarvellSpiFlashProtocolGuid, + NULL, + (VOID **)&SpiFlashProtocol + ); + if (EFI_ERROR(Status)) { + Print (L"sf: Cannot locate SpiFlash protocol\n"); + return SHELL_ABORTED; + } + + Status = gBS->LocateProtocol ( + &gMarvellSpiMasterProtocolGuid, + NULL, + (VOID **)&SpiMasterProtocol + ); + if (EFI_ERROR(Status)) { + Print (L"sf: Cannot locate SpiMaster protocol\n"); + return SHELL_ABORTED; + } + + // Parse Shell command line + Status = ShellInitialize (); + if (EFI_ERROR (Status)) { + Print (L"sf: Cannot initialize Shell\n"); + ASSERT_EFI_ERROR (Status); + return SHELL_ABORTED; + } + + Status = ShellCommandLineParse (ParamList, &CheckPackage, &ProblemParam, TRUE); + if (EFI_ERROR (Status)) { + Print (L"sf: Error while parsing command line\n"); + return SHELL_ABORTED; + } + + if (ShellCommandLineGetFlag (CheckPackage, L"help")) { + SfUsage(); + return EFI_SUCCESS; + } + + // Check flags provided by user + Flag |= (ShellCommandLineGetFlag (CheckPackage, L"probe") << 0); + Flag |= (ShellCommandLineGetFlag (CheckPackage, L"read") << 1); + Flag |= (ShellCommandLineGetFlag (CheckPackage, L"readfile") << 2); + Flag |= (ShellCommandLineGetFlag (CheckPackage, L"write") << 3); + Flag |= (ShellCommandLineGetFlag (CheckPackage, L"writefile") << 4); + Flag |= (ShellCommandLineGetFlag (CheckPackage, L"erase") << 5); + Flag |= (ShellCommandLineGetFlag (CheckPackage, L"update") << 6); + Flag |= (ShellCommandLineGetFlag (CheckPackage, L"updatefile") << 7); + + if (InitFlag && !(Flag & PROBE)) { + Print (L"Please run sf probe\n"); + return EFI_SUCCESS; + } + + CheckFlag = Flag; + for (I = 0; CheckFlag; CheckFlag >>= 1) { + I += CheckFlag & 1; + if (I > 1) { + Print (L"sf: Too many flags\n"); + SfUsage(); + return SHELL_ABORTED; + } + } + + // Setup new spi device + Slave = SpiMasterProtocol->SetupDevice (SpiMasterProtocol, 0, 0); + if (Slave == NULL) { + Print(L"sf: Cannot allocate SPI device!\n"); + return SHELL_ABORTED; + } + + switch (Flag) { + case PROBE: + // Probe spi bus + Status = FlashProbe (Slave); + if (EFI_ERROR(Status)) { + // No supported spi flash detected + return SHELL_ABORTED; + } else { + return Status; + } + break; + // Fall through + case READ: + case WRITE: + case UPDATE: + AddressStr = ShellCommandLineGetRawValue (CheckPackage, 1); + OffsetStr = ShellCommandLineGetRawValue (CheckPackage, 2); + LengthStr = ShellCommandLineGetRawValue (CheckPackage, 3); + AddrFlag = TRUE; + break; + case ERASE: + OffsetStr = ShellCommandLineGetRawValue (CheckPackage, 1); + LengthStr = ShellCommandLineGetRawValue (CheckPackage, 2); + break; + case READ_FILE: + FileStr = ShellCommandLineGetRawValue (CheckPackage, 1); + OffsetStr = ShellCommandLineGetRawValue (CheckPackage, 2); + LengthStr = ShellCommandLineGetRawValue (CheckPackage, 3); + FileFlag = TRUE; + break; + case WRITE_FILE: + case UPDATE_FILE: + FileStr = ShellCommandLineGetRawValue (CheckPackage, 1); + OffsetStr = ShellCommandLineGetRawValue (CheckPackage, 2); + LengthFlag = FALSE; + FileFlag = TRUE; + break; + } + + // Read address parameter + if ((AddressStr == NULL) & AddrFlag) { + Print (L"sf: No address parameter!\n"); + return SHELL_ABORTED; + } else if (AddrFlag) { + Address = ShellHexStrToUintn (AddressStr); + if (Address == (UINTN)(-1)) { + Print (L"sf: Wrong address parameter\n"); + return SHELL_ABORTED; + } + } + + // Read offset parameter + if (OffsetStr == NULL) { + Print (L"sf: No offset Parameter!\n"); + return SHELL_ABORTED; + } else { + Offset = ShellHexStrToUintn (OffsetStr); + if (Offset < 0) { + Print (L"sf: Wrong offset parameter: %s", OffsetStr); + return SHELL_ABORTED; + } + } + + // Read length parameter + if ((LengthStr == NULL) & LengthFlag) { + Print (L"sf: No lenght parameter!\n"); + return SHELL_ABORTED; + } else if (LengthFlag) { + ByteCount = ShellStrToUintn (LengthStr); + if (ByteCount < 0) { + Print (L"sf: Wrong length parameter %s!\n", LengthStr); + return SHELL_ABORTED; + } + } + + if (FileFlag) { + // Read FilePath parameter + if (FileStr == NULL) { + Print (L"sf: No FilePath parameter!\n"); + return SHELL_ABORTED; + } else { + FilePath = (CHAR16 *) FileStr; + Status = ShellIsFile (FilePath); + // When read file into flash, file doesn't have to exist + if (EFI_ERROR(Status && !(Flag & READ_FILE))) { + Print (L"sf: Wrong FilePath parameter!\n"); + return SHELL_ABORTED; + } + } + + Status = OpenAndPrepareFile (FilePath, &FileHandle); + if (EFI_ERROR(Status)) { + Print (L"sf: Error while preparing file\n"); + return SHELL_ABORTED; + } + + // Get file size in order to check correctness at the end of transfer + if (Flag & (WRITE_FILE | UPDATE_FILE)) { + Status = FileHandleGetSize (FileHandle, &FileSize); + if (EFI_ERROR (Status)) { + Print (L"sf: Cannot get file size\n"); + } + ByteCount = (UINTN) FileSize; + } + + FileBuffer = AllocateZeroPool ((UINTN) ByteCount); + if (FileBuffer == NULL) { + Print (L"sf: Cannot allocate memory\n"); + goto Error_Close_File; + } + + // Read file content and store it in FileBuffer + if (Flag & (WRITE_FILE | UPDATE_FILE)) { + Status = FileHandleRead (FileHandle, &ByteCount, FileBuffer); + if (EFI_ERROR (Status)) { + Print (L"sf: Read from file error\n"); + goto Error_Free_Buffer; + } else if (ByteCount != (UINTN) FileSize) { + Print (L"sf: Not whole file read. Abort\n"); + goto Error_Free_Buffer; + } + } + } + + Buffer = (UINT8 *) Address; + if (FileFlag) { + Buffer = FileBuffer; + } + + switch (Flag) { + case READ: + case READ_FILE: + Status = SpiFlashProtocol->Read (Slave, Offset, ByteCount, Buffer); + break; + case ERASE: + Status = SpiFlashProtocol->Erase (Slave, Offset, ByteCount); + break; + case WRITE: + case WRITE_FILE: + Status = SpiFlashProtocol->Write (Slave, Offset, ByteCount, Buffer); + break; + case UPDATE: + case UPDATE_FILE: + Status = SpiFlashProtocol->Update (Slave, Offset, ByteCount, Buffer); + break; + } + + SpiMasterProtocol->FreeDevice(Slave); + + if (EFI_ERROR (Status)) { + Print (L"sf: Error while performing spi transfer\n"); + return SHELL_ABORTED; + } + + switch (Flag) { + case ERASE: + Print (L"sf: %d bytes succesfully erased at offset 0x%x\n", ByteCount, + Offset); + break; + case WRITE: + case WRITE_FILE: + Print (L"sf: Write %d bytes at offset 0x%x\n", ByteCount, Offset); + break; + case UPDATE: + case UPDATE_FILE: + Print (L"sf: Update %d bytes at offset 0x%x\n", ByteCount, Offset); + break; + case READ: + Print (L"sf: Read %d bytes from offset 0x%x\n", ByteCount, Offset); + break; + case READ_FILE: + Status = FileHandleWrite (FileHandle, &ByteCount, FileBuffer); + if (EFI_ERROR(Status)) { + Print (L"sf: Error while writing into file\n"); + goto Error_Free_Buffer; + } + break; + } + + if (FileFlag) { + FreePool (FileBuffer); + + if (FileHandle != NULL) { + ShellCloseFile (&FileHandle); + } + } + + return EFI_SUCCESS; + +Error_Free_Buffer: + FreePool (FileBuffer); +Error_Close_File: + ShellCloseFile (&FileHandle); + return SHELL_ABORTED; +} + +EFI_STATUS +EFIAPI +ShellSpiFlashLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + gShellSfHiiHandle = NULL; + + gShellSfHiiHandle = HiiAddPackages ( + &gShellSfHiiGuid, gImageHandle, + UefiShellSpiFlashLibStrings, NULL + ); + if (gShellSfHiiHandle == NULL) { + return EFI_DEVICE_ERROR; + } + + ShellCommandRegisterCommandName ( + L"sf", ShellCommandRunSpiFlash, ShellCommandGetManFileNameSpiFlash, 0, + L"sf", TRUE , gShellSfHiiHandle, STRING_TOKEN (STR_GET_HELP_SF) + ); + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +ShellSpiFlashLibDestructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + + if (gShellSfHiiHandle != NULL) { + HiiRemovePackages (gShellSfHiiHandle); + } + return EFI_SUCCESS; +} diff --git a/Applications/SpiTool/SpiFlashCmd.inf b/Applications/SpiTool/SpiFlashCmd.inf new file mode 100644 index 0000000..d91fdf3 --- /dev/null +++ b/Applications/SpiTool/SpiFlashCmd.inf @@ -0,0 +1,75 @@ +# +# Marvell BSD License Option +# +# If you received this File from Marvell, you may opt to use, redistribute +# and/or modify this File under the following licensing terms. +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# * Neither the name of Marvell nor the names of its contributors may be +# used to endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +[Defines] + INF_VERSION = 0x00010006 + BASE_NAME = UefiShellSpiFlashLib + FILE_GUID = 2f2dd8c9-221f-4acf-afe5-5897264c5774 + MODULE_TYPE = UEFI_APPLICATION + VERSION_STRING = 0.1 + LIBRARY_CLASS = NULL|UEFI_APPLICATION UEFI_DRIVER + CONSTRUCTOR = ShellSpiFlashLibConstructor + DESTRUCTOR = ShellSpiFlashLibDestructor + +[Sources] + SpiFlashCmd.c + SpiFlashCmd.uni + +[Packages] + MdePkg/MdePkg.dec + ShellPkg/ShellPkg.dec + MdeModulePkg/MdeModulePkg.dec + OpenPlatformPkg/Platforms/Marvell/Marvell.dec + +[LibraryClasses] + UefiLib + UefiBootServicesTableLib + MemoryAllocationLib + BaseLib + BaseMemoryLib + DebugLib + ShellCommandLib + ShellLib + UefiLib + UefiRuntimeServicesTableLib + PcdLib + HiiLib + FileHandleLib + +[Pcd] + gMarvellTokenSpaceGuid.PcdSpiFlashId + +[Protocols] + gMarvellSpiFlashProtocolGuid + gMarvellSpiMasterProtocolGuid + +[Guids] + gShellSfHiiGuid diff --git a/Applications/SpiTool/SpiFlashCmd.uni b/Applications/SpiTool/SpiFlashCmd.uni new file mode 100644 index 0000000000000000000000000000000000000000..3f25663ed79f1e7a8f6f7ca3143864e04a506fac GIT binary patch literal 7216 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
literal 0 HcmV?d00001
diff --git a/Platforms/Marvell/Marvell.dec b/Platforms/Marvell/Marvell.dec index a2d1956..e63add4 100644 --- a/Platforms/Marvell/Marvell.dec +++ b/Platforms/Marvell/Marvell.dec @@ -53,6 +53,7 @@ gMarvellTokenSpaceGuid = { 0xf995c6c8, 0xbc9b, 0x4e93, { 0xbd, 0xcf, 0x49, 0x90, 0xc6, 0xe7, 0x8c, 0x7f } }
gShellEepromHiiGuid = { 0xb2f4c714, 0x147f, 0x4ff7, { 0x82, 0x1b, 0xce, 0x7b, 0x91, 0x7f, 0x5f, 0x2f } } + gShellSfHiiGuid = { 0x03a67756, 0x8cde, 0x4638, { 0x82, 0x34, 0x4a, 0x0f, 0x6d, 0x58, 0x81, 0x39 } }
[PcdsFixedAtBuild.common] #MPP