summaryrefslogtreecommitdiff
path: root/Silicon/Marvell/Applications
diff options
context:
space:
mode:
Diffstat (limited to 'Silicon/Marvell/Applications')
-rw-r--r--Silicon/Marvell/Applications/EepromCmd/EepromCmd.c397
-rw-r--r--Silicon/Marvell/Applications/EepromCmd/EepromCmd.inf71
-rw-r--r--Silicon/Marvell/Applications/EepromCmd/EepromCmd.unibin0 -> 6816 bytes
-rw-r--r--Silicon/Marvell/Applications/FirmwareUpdate/FUpdate.c398
-rw-r--r--Silicon/Marvell/Applications/FirmwareUpdate/FUpdate.inf73
-rw-r--r--Silicon/Marvell/Applications/FirmwareUpdate/FUpdate.unibin0 -> 5190 bytes
-rw-r--r--Silicon/Marvell/Applications/SpiTool/SpiFlashCmd.c516
-rw-r--r--Silicon/Marvell/Applications/SpiTool/SpiFlashCmd.inf77
-rw-r--r--Silicon/Marvell/Applications/SpiTool/SpiFlashCmd.unibin0 -> 7216 bytes
9 files changed, 1532 insertions, 0 deletions
diff --git a/Silicon/Marvell/Applications/EepromCmd/EepromCmd.c b/Silicon/Marvell/Applications/EepromCmd/EepromCmd.c
new file mode 100644
index 0000000000..f43e411067
--- /dev/null
+++ b/Silicon/Marvell/Applications/EepromCmd/EepromCmd.c
@@ -0,0 +1,397 @@
+/********************************************************************************
+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/UefiRuntimeServicesTableLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/PrintLib.h>
+#include <Library/HiiLib.h>
+
+#include <Library/UefiLib.h>
+#include <Library/ShellCEntryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#include <Protocol/Eeprom.h>
+
+#define I2C_DEVICE_INDEX(bus, address) (((address) & 0xffff) | (bus) << 16)
+#define I2C_DEVICE_ADDRESS(index) ((index) & 0xffff)
+#define I2C_DEVICE_BUS(index) ((index) >> 16)
+
+CONST CHAR16 ShellEepromFileName[] = L"ShellCommand";
+EFI_HANDLE ShellEepromHiiHandle = NULL;
+
+STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
+ {L"-d", TypeValue},
+ {L"-m", TypeValue},
+ {L"read", TypeFlag},
+ {L"write", TypeFlag},
+ {L"list", TypeFlag},
+ {L"help", TypeFlag},
+ {NULL , TypeMax}
+ };
+
+/**
+ Return the file name of the help text file if not using HII.
+
+ @return The string pointer to the file name.
+**/
+STATIC
+CONST CHAR16*
+EFIAPI
+ShellCommandGetManFileNameEeprom (
+ VOID
+ )
+{
+ return ShellEepromFileName;
+}
+
+STATIC
+VOID
+Usage (
+ VOID
+ )
+{
+ Print (L"Basic EEPROM commands:\n"
+ "eeprom [read] [write] [list] [<Chip>] [<Bus>][<Address>] [<Length>] [-d <Data>] [-m <Source>]\n"
+ "All modes except 'list' require Address, Length and Chip set.\n\n"
+ "read - read from EEPROM\n"
+ "write - write Data to EEPROM, requires -d\n"
+ "list - list available EEPROM devices\n\n"
+ "-m - transfer from/to RAM memory\n\n"
+ "Chip - EEPROM bus address\n"
+ "Bus - I2C bus address\n"
+ "Address - address in EEPROM to read/write\n"
+ "Data - data byte to be written\n"
+ "Length - length of data to read/write/copy\n"
+ "Source - address of data in RAM to be copied\n"
+ "Examples:\n"
+ "List devices:\n"
+ " eeprom list\n"
+ "Read 16 bytes from address 0x0 in chip 0x57:\n"
+ " eeprom read 0x57 0x0 0x0 0x10\n"
+ "Fill 16 bytes with 0xab at address 0x0 in chip 0x57:\n"
+ " eeprom write 0x57 0x0 0x0 0x10 -d 0xab\n"
+ "Copy 32 bytes from 0x2000000 in RAM to EEPROM:\n"
+ " eeprom write 0x57 0x0 0x0 0x20 -m 0x2000000\n"
+ "Copy 32 bytes from EEPROM to RAM:\n"
+ " eeprom read 0x57 0x0 0x0 0x20 -m 0x2000000\n"
+ );
+}
+
+STATIC
+EFI_STATUS
+EepromList (
+ )
+{
+ EFI_HANDLE *HandleBuffer;
+ EFI_STATUS Status;
+ UINTN ProtocolCount;
+ MARVELL_EEPROM_PROTOCOL *EepromProtocol;
+ UINTN i;
+ Status = gBS->LocateHandleBuffer ( ByProtocol,
+ &gMarvellEepromProtocolGuid,
+ NULL,
+ &ProtocolCount,
+ &HandleBuffer
+ );
+ if (ProtocolCount == 0) {
+ Print (L"0 devices found.\n");
+ } else {
+ Print (L"%u devices found: ", ProtocolCount);
+ }
+
+ for (i = 0; i < ProtocolCount; i++) {
+ Status = gBS->OpenProtocol (
+ HandleBuffer[i],
+ &gMarvellEepromProtocolGuid,
+ (VOID **) &EepromProtocol,
+ gImageHandle,
+ NULL,
+ EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL );
+ Print (L"0x%x at bus %d\n", I2C_DEVICE_ADDRESS(EepromProtocol->Identifier),
+ I2C_DEVICE_BUS(EepromProtocol->Identifier));
+ Status = gBS->CloseProtocol ( HandleBuffer[i],
+ &gMarvellEepromProtocolGuid,
+ gImageHandle,
+ NULL );
+ }
+ Print (L"\n");
+ return Status;
+}
+
+STATIC
+EFI_STATUS
+EepromLocateProtocol (
+ IN UINT32 Identifier,
+ OUT EFI_HANDLE *FoundHandle,
+ OUT MARVELL_EEPROM_PROTOCOL **FoundEepromProtocol
+ )
+{
+ EFI_HANDLE *HandleBuffer;
+ EFI_STATUS Status;
+ UINTN ProtocolCount;
+ MARVELL_EEPROM_PROTOCOL *EepromProtocol;
+ UINTN i;
+ Status = gBS->LocateHandleBuffer ( ByProtocol,
+ &gMarvellEepromProtocolGuid,
+ NULL,
+ &ProtocolCount,
+ &HandleBuffer
+ );
+ if (EFI_ERROR(Status))
+ return Status;
+
+ for (i = 0; i < ProtocolCount; i++) {
+ Status = gBS->OpenProtocol (
+ HandleBuffer[i],
+ &gMarvellEepromProtocolGuid,
+ (VOID **) &EepromProtocol,
+ gImageHandle,
+ NULL,
+ EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL );
+ if (EepromProtocol->Identifier == Identifier) {
+ *FoundEepromProtocol = EepromProtocol;
+ *FoundHandle = HandleBuffer[i];
+ return EFI_SUCCESS;
+ }
+ Status = gBS->CloseProtocol ( HandleBuffer[i],
+ &gMarvellEepromProtocolGuid,
+ gImageHandle,
+ NULL );
+ }
+ *FoundEepromProtocol = NULL;
+ return EFI_UNSUPPORTED;
+}
+
+SHELL_STATUS
+EFIAPI
+ShellCommandRunEeprom (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ LIST_ENTRY *CheckPackage;
+ CHAR16 *ProblemParam;
+ CONST CHAR16 *ValueStr;
+ UINTN Address, Length, Chip, Source, Bus;
+ UINT8 Data;
+ UINT8 *Buffer;
+ BOOLEAN ReadMode, MemMode;
+ EFI_HANDLE Handle, ProtHandle;
+ MARVELL_EEPROM_PROTOCOL *EepromProtocol = NULL;
+ UINTN Count, HandleSize;
+
+ Handle = NULL;
+ Source = 0;
+ HandleSize = 2 * sizeof (EFI_HANDLE);
+
+ Status = gBS->LocateHandle (ByProtocol, &gMarvellEepromProtocolGuid, NULL,
+ &HandleSize, &ProtHandle);
+ if (EFI_ERROR(Status)) {
+ DEBUG((DEBUG_INFO, "No Eeprom protocol, connect I2C stack\n"));
+ Status = gBS->LocateHandle (ByProtocol, &gEfiI2cMasterProtocolGuid, NULL,
+ &HandleSize, &ProtHandle);
+ if (EFI_ERROR(Status)) {
+ Print (L"Failed to locate I2cMaster protocol, abort!\n");
+ return SHELL_ABORTED;
+ }
+ Status = gBS->ConnectController (ProtHandle, NULL, NULL, TRUE);
+ if (EFI_ERROR(Status)) {
+ Print (L"Cannot connect I2C stack, abort!\n");
+ return SHELL_ABORTED;
+ }
+ }
+
+ Status = ShellInitialize ();
+ if (EFI_ERROR (Status)) {
+ Print (L"Error - failed to initialize shell\n");
+ return SHELL_ABORTED;
+ }
+
+ Status = ShellCommandLineParse (ParamList, &CheckPackage, &ProblemParam, TRUE);
+ if (EFI_ERROR (Status)) {
+ Print (L"Error - failed to parse command line\n");
+ return SHELL_ABORTED;
+ }
+
+ if (ShellCommandLineGetFlag (CheckPackage, L"list")) {
+ EepromList();
+ return SHELL_SUCCESS;
+ }
+
+ if (ShellCommandLineGetFlag (CheckPackage, L"help")) {
+ Usage();
+ return SHELL_SUCCESS;
+ }
+
+ if (ShellCommandLineGetCount(CheckPackage) < 4) {
+ Print (L"Not enough arguments given.\n");
+ Usage();
+ }
+
+ ReadMode = ShellCommandLineGetFlag (CheckPackage, L"read");
+ if (ReadMode == ShellCommandLineGetFlag (CheckPackage, L"write")) {
+ Print (L"Error - type read, write, list or help.\n");
+ return SHELL_INVALID_PARAMETER;
+ }
+
+ MemMode = ShellCommandLineGetFlag (CheckPackage, L"-m");
+ Data = 0;
+ if (!ReadMode && !MemMode) {
+ ValueStr = ShellCommandLineGetValue (CheckPackage, L"-d");
+ if (ValueStr == NULL) {
+ Print (L"Error - no data to write.\n");
+ return SHELL_INVALID_PARAMETER;
+ }
+ Data = ShellHexStrToUintn (ValueStr);
+ }
+
+ ValueStr = ShellCommandLineGetRawValue(CheckPackage, 1);
+ Chip = ShellHexStrToUintn (ValueStr);
+
+ ValueStr = ShellCommandLineGetRawValue(CheckPackage, 2);
+ Bus = ShellHexStrToUintn (ValueStr);
+
+ ValueStr = ShellCommandLineGetRawValue(CheckPackage, 3);
+ Address = ShellHexStrToUintn (ValueStr);
+
+ ValueStr = ShellCommandLineGetRawValue(CheckPackage, 4);
+ Length = ShellHexStrToUintn (ValueStr);
+
+ if (MemMode) {
+ ValueStr = ShellCommandLineGetValue (CheckPackage, L"-m");
+ if (ValueStr == NULL) {
+ Print (L"Error - no memory address given.\n");
+ return SHELL_INVALID_PARAMETER;
+ }
+ Source = ShellHexStrToUintn (ValueStr);
+ }
+
+ EepromLocateProtocol (I2C_DEVICE_INDEX(Bus, Chip), &Handle, &EepromProtocol);
+ if (EepromProtocol == NULL) {
+ Print (L"Failed to locate EEPROM protocol.\n");
+ return SHELL_INVALID_PARAMETER;
+ }
+
+ if (MemMode) {
+ Buffer = (VOID *) Source;
+ } else {
+ Buffer = AllocateZeroPool (Length);
+ if (Buffer == NULL) {
+ Status = SHELL_OUT_OF_RESOURCES;
+ Print (L"Error - out of resources.\n");
+ goto out_close;
+ }
+ if (!ReadMode) {
+ for (Count = 0; Count < Length; Count++)
+ Buffer[Count] = Data;
+ }
+ }
+ EepromProtocol->Transfer(EepromProtocol, Address, Length, Buffer,
+ ReadMode ? EEPROM_READ : EEPROM_WRITE);
+
+ if (MemMode) {
+ Print (L"Transfered succesfully.\n");
+ } else {
+ Print (L"Transfered:\n");
+ for (Count = 0; Count < Length; Count++) {
+ Print(L"0x%x ", Buffer[Count]);
+ if (Count % 8 == 7)
+ Print(L"\n");
+ }
+ Print (L"\n");
+ }
+
+ Status = SHELL_SUCCESS;
+
+ if (!MemMode)
+ FreePool(Buffer);
+out_close:
+ gBS->CloseProtocol ( Handle,
+ &gMarvellEepromProtocolGuid,
+ gImageHandle,
+ NULL );
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+ShellEepromCmdLibConstructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+
+ ShellEepromHiiHandle = NULL;
+
+ ShellEepromHiiHandle = HiiAddPackages (
+ &gShellEepromHiiGuid, gImageHandle,
+ UefiShellEepromLibStrings, NULL
+ );
+ if (ShellEepromHiiHandle == NULL) {
+ Print (L"Filed to add Hii package\n");
+ return EFI_DEVICE_ERROR;
+ }
+ ShellCommandRegisterCommandName (
+ L"eeprom", ShellCommandRunEeprom, ShellCommandGetManFileNameEeprom, 0,
+ L"eeprom", TRUE , ShellEepromHiiHandle, STRING_TOKEN (STR_GET_HELP_EEPROM)
+ );
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+ShellEepromCmdLibDestructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+
+ if (ShellEepromHiiHandle != NULL) {
+ HiiRemovePackages (ShellEepromHiiHandle);
+ }
+ return EFI_SUCCESS;
+}
diff --git a/Silicon/Marvell/Applications/EepromCmd/EepromCmd.inf b/Silicon/Marvell/Applications/EepromCmd/EepromCmd.inf
new file mode 100644
index 0000000000..c86ead1b7d
--- /dev/null
+++ b/Silicon/Marvell/Applications/EepromCmd/EepromCmd.inf
@@ -0,0 +1,71 @@
+#
+# 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 = UefiShellEepromLib
+ FILE_GUID = adf4b61c-2ca3-4e1a-9597-99282f5a4aa2
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 0.1
+ LIBRARY_CLASS = NULL|UEFI_APPLICATION UEFI_DRIVER
+ CONSTRUCTOR = ShellEepromCmdLibConstructor
+ DESTRUCTOR = ShellEepromCmdLibDestructor
+
+[Sources]
+ EepromCmd.c
+ EepromCmd.uni
+
+[Packages]
+ MdePkg/MdePkg.dec
+ ShellPkg/ShellPkg.dec
+ StdLib/StdLib.dec
+ MdeModulePkg/MdeModulePkg.dec
+ Silicon/Marvell/Marvell.dec
+
+[LibraryClasses]
+ UefiLib
+ UefiBootServicesTableLib
+ MemoryAllocationLib
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ ShellCommandLib
+ ShellLib
+ UefiLib
+ UefiRuntimeServicesTableLib
+ PcdLib
+
+[Protocols]
+ gMarvellEepromProtocolGuid
+ gEfiI2cMasterProtocolGuid
+
+[Guids]
+ gShellEepromHiiGuid
diff --git a/Silicon/Marvell/Applications/EepromCmd/EepromCmd.uni b/Silicon/Marvell/Applications/EepromCmd/EepromCmd.uni
new file mode 100644
index 0000000000..e41c6d812e
--- /dev/null
+++ b/Silicon/Marvell/Applications/EepromCmd/EepromCmd.uni
Binary files differ
diff --git a/Silicon/Marvell/Applications/FirmwareUpdate/FUpdate.c b/Silicon/Marvell/Applications/FirmwareUpdate/FUpdate.c
new file mode 100644
index 0000000000..9ccb1c749b
--- /dev/null
+++ b/Silicon/Marvell/Applications/FirmwareUpdate/FUpdate.c
@@ -0,0 +1,398 @@
+/*******************************************************************************
+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 <ShellBase.h>
+#include <Uefi.h>
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/FileHandleLib.h>
+#include <Library/HiiLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PrintLib.h>
+#include <Library/ShellCEntryLib.h>
+#include <Library/ShellCommandLib.h>
+#include <Library/ShellLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+
+#include <Protocol/Spi.h>
+#include <Protocol/SpiFlash.h>
+
+#define CMD_NAME_STRING L"fupdate"
+
+#define MAIN_HDR_MAGIC 0xB105B002
+
+STATIC MARVELL_SPI_FLASH_PROTOCOL *SpiFlashProtocol;
+STATIC MARVELL_SPI_MASTER_PROTOCOL *SpiMasterProtocol;
+
+STATIC CONST CHAR16 gShellFUpdateFileName[] = L"ShellCommands";
+STATIC EFI_HANDLE gShellFUpdateHiiHandle = NULL;
+
+STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
+ {L"help", TypeFlag},
+ {NULL , TypeMax}
+ };
+
+typedef struct { // Bytes
+ UINT32 Magic; // 0-3
+ UINT32 PrologSize; // 4-7
+ UINT32 PrologChecksum; // 8-11
+ UINT32 BootImageSize; // 12-15
+ UINT32 BootImageChecksum; // 16-19
+ UINT32 Reserved0; // 20-23
+ UINT32 LoadAddr; // 24-27
+ UINT32 ExecAddr; // 28-31
+ UINT8 UartConfig; // 32
+ UINT8 Baudrate; // 33
+ UINT8 ExtCount; // 34
+ UINT8 AuxFlags; // 35
+ UINT32 IoArg0; // 36-39
+ UINT32 IoArg1; // 40-43
+ UINT32 IoArg2; // 43-47
+ UINT32 IoArg3; // 48-51
+ UINT32 Reserved1; // 52-55
+ UINT32 Reserved2; // 56-59
+ UINT32 Reserved3; // 60-63
+} MV_FIRMWARE_IMAGE_HEADER;
+
+STATIC
+EFI_STATUS
+SpiFlashProbe (
+ IN SPI_DEVICE *Slave
+ )
+{
+ EFI_STATUS Status;
+
+ // Read SPI flash ID
+ Status = SpiFlashProtocol->ReadId (Slave, FALSE);
+ if (EFI_ERROR (Status)) {
+ return SHELL_ABORTED;
+ }
+
+ Status = SpiFlashProtocol->Init (SpiFlashProtocol, Slave);
+ if (EFI_ERROR(Status)) {
+ Print (L"%s: Cannot initialize flash device\n", CMD_NAME_STRING);
+ return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+CheckImageHeader (
+ IN OUT UINTN *ImageHeader
+ )
+{
+ MV_FIRMWARE_IMAGE_HEADER *Header;
+ UINT32 HeaderLength, Checksum, ChecksumBackup;
+
+ Header = (MV_FIRMWARE_IMAGE_HEADER *)ImageHeader;
+ HeaderLength = Header->PrologSize;
+ ChecksumBackup = Header->PrologChecksum;
+
+ // Compare magic number
+ if (Header->Magic != MAIN_HDR_MAGIC) {
+ Print (L"%s: Bad Image magic 0x%08x != 0x%08x\n", CMD_NAME_STRING, Header->Magic, MAIN_HDR_MAGIC);
+ return EFI_DEVICE_ERROR;
+ }
+
+ // The checksum field is discarded from calculation
+ Header->PrologChecksum = 0;
+
+ Checksum = CalculateSum32 ((UINT32 *)Header, HeaderLength);
+ if (Checksum != ChecksumBackup) {
+ Print (L"%s: Bad Image checksum. 0x%x != 0x%x\n", CMD_NAME_STRING, Checksum, ChecksumBackup);
+ return EFI_DEVICE_ERROR;
+ }
+
+ // Restore checksum backup
+ Header->PrologChecksum = ChecksumBackup;
+
+ return 0;
+}
+
+STATIC
+EFI_STATUS
+PrepareFirmwareImage (
+ IN LIST_ENTRY *CheckPackage,
+ IN OUT SHELL_FILE_HANDLE *FileHandle,
+ IN OUT UINTN **FileBuffer,
+ IN OUT UINT64 *FileSize
+ )
+{
+ CONST CHAR16 *FileStr;
+ EFI_STATUS Status;
+ UINT64 OpenMode;
+ UINTN *Buffer;
+
+ // Parse string from commandline
+ FileStr = ShellCommandLineGetRawValue (CheckPackage, 1);
+ if (FileStr == NULL) {
+ Print (L"%s: No image specified\n", CMD_NAME_STRING);
+ return EFI_INVALID_PARAMETER;
+ } else {
+ Status = ShellIsFile (FileStr);
+ if (EFI_ERROR(Status)) {
+ Print (L"%s: File not found\n", CMD_NAME_STRING);
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ // Obtain file size
+ OpenMode = EFI_FILE_MODE_READ;
+
+ Status = ShellOpenFileByName (FileStr, FileHandle, OpenMode, 0);
+ if (EFI_ERROR (Status)) {
+ Print (L"%s: Cannot open Image file\n", CMD_NAME_STRING);
+ return EFI_DEVICE_ERROR;
+ }
+
+ Status = FileHandleGetSize (*FileHandle, FileSize);
+ if (EFI_ERROR (Status)) {
+ Print (L"%s: Cannot get Image file size\n", CMD_NAME_STRING);
+ }
+
+ // Read Image header into buffer
+ Buffer = AllocateZeroPool (*FileSize);
+
+ Status = FileHandleRead (*FileHandle, (UINTN *)FileSize, Buffer);
+ if (EFI_ERROR (Status)) {
+ Print (L"%s: Cannot read Image file header\n", CMD_NAME_STRING);
+ ShellCloseFile (FileHandle);
+ FreePool (Buffer);
+ return EFI_DEVICE_ERROR;
+ }
+
+ *FileBuffer = Buffer;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Return the file name of the help text file if not using HII.
+
+ @return The string pointer to the file name.
+**/
+STATIC
+CONST CHAR16*
+EFIAPI
+ShellCommandGetManFileNameFUpdate (
+ VOID
+ )
+{
+ return gShellFUpdateFileName;
+}
+
+STATIC
+VOID
+FUpdateUsage (
+ VOID
+ )
+{
+ Print (L"\nFirmware update command\n"
+ "fupdate <LocalFilePath>\n\n"
+ "LocalFilePath - path to local firmware image file\n"
+ "Example:\n"
+ "Update firmware from file fs2:flash-image.bin\n"
+ " fupdate fs2:flash-image.bin\n"
+ );
+}
+
+STATIC
+SHELL_STATUS
+EFIAPI
+ShellCommandRunFUpdate (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ IN SHELL_FILE_HANDLE FileHandle;
+ SPI_DEVICE *Slave = NULL;
+ UINT64 FileSize;
+ UINTN *FileBuffer = NULL;
+ CHAR16 *ProblemParam;
+ LIST_ENTRY *CheckPackage;
+ EFI_STATUS Status;
+
+ // Locate SPI protocols
+ Status = gBS->LocateProtocol (
+ &gMarvellSpiFlashProtocolGuid,
+ NULL,
+ (VOID **)&SpiFlashProtocol
+ );
+
+ if (EFI_ERROR(Status)) {
+ Print (L"%s: Cannot locate SpiFlash protocol\n", CMD_NAME_STRING);
+ return SHELL_ABORTED;
+ }
+
+ Status = gBS->LocateProtocol (
+ &gMarvellSpiMasterProtocolGuid,
+ NULL,
+ (VOID **)&SpiMasterProtocol
+ );
+
+ if (EFI_ERROR(Status)) {
+ Print (L"%s: Cannot locate SpiMaster protocol\n", CMD_NAME_STRING);
+ return SHELL_ABORTED;
+ }
+
+ // Parse command line
+ Status = ShellInitialize ();
+ if (EFI_ERROR (Status)) {
+ Print (L"%s: Error while initializing Shell\n", CMD_NAME_STRING);
+ ASSERT_EFI_ERROR (Status);
+ return SHELL_ABORTED;
+ }
+
+ Status = ShellCommandLineParse (ParamList, &CheckPackage, &ProblemParam, TRUE);
+ if (EFI_ERROR (Status)) {
+ Print (L"%s: Invalid parameter\n", CMD_NAME_STRING);
+ return SHELL_ABORTED;
+ }
+
+ if (ShellCommandLineGetFlag (CheckPackage, L"help")) {
+ FUpdateUsage();
+ return EFI_SUCCESS;
+ }
+
+ // Prepare local file to be burned into flash
+ Status = PrepareFirmwareImage (CheckPackage, &FileHandle, &FileBuffer, &FileSize);
+ if (EFI_ERROR(Status)) {
+ return SHELL_ABORTED;
+ }
+
+ // Check image checksum and magic
+ Status = CheckImageHeader (FileBuffer);
+ if (EFI_ERROR(Status)) {
+ goto HeaderError;
+ }
+
+ // Setup and probe SPI flash
+ Slave = SpiMasterProtocol->SetupDevice (SpiMasterProtocol, Slave, 0, 0);
+ if (Slave == NULL) {
+ Print(L"%s: Cannot allocate SPI device!\n", CMD_NAME_STRING);
+ goto HeaderError;
+ }
+
+ Status = SpiFlashProbe (Slave);
+ if (EFI_ERROR(Status)) {
+ Print (L"%s: Error while performing SPI flash probe\n", CMD_NAME_STRING);
+ goto FlashProbeError;
+ }
+
+ // Update firmware image in flash at offset 0x0
+ Status = SpiFlashProtocol->Update (Slave, 0, FileSize, (UINT8 *)FileBuffer);
+
+ // Release resources
+ SpiMasterProtocol->FreeDevice(Slave);
+ FreePool (FileBuffer);
+ ShellCloseFile (&FileHandle);
+
+ if (EFI_ERROR(Status)) {
+ Print (L"%s: Error while performing flash update\n", CMD_NAME_STRING);
+ return SHELL_ABORTED;
+ }
+
+ Print (L"%s: Update %d bytes at offset 0x0 succeeded!\n", CMD_NAME_STRING, FileSize);
+
+ return EFI_SUCCESS;
+
+FlashProbeError:
+ SpiMasterProtocol->FreeDevice(Slave);
+HeaderError:
+ FreePool (FileBuffer);
+ ShellCloseFile (&FileHandle);
+
+ return SHELL_ABORTED;
+}
+
+EFI_STATUS
+EFIAPI
+ShellFUpdateCommandConstructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ gShellFUpdateHiiHandle = NULL;
+
+ gShellFUpdateHiiHandle = HiiAddPackages (
+ &gShellFUpdateHiiGuid,
+ gImageHandle,
+ UefiShellFUpdateCommandLibStrings,
+ NULL
+ );
+
+ if (gShellFUpdateHiiHandle == NULL) {
+ Print (L"%s: Cannot add Hii package\n", CMD_NAME_STRING);
+ return EFI_DEVICE_ERROR;
+ }
+
+ Status = ShellCommandRegisterCommandName (
+ CMD_NAME_STRING,
+ ShellCommandRunFUpdate,
+ ShellCommandGetManFileNameFUpdate,
+ 0,
+ CMD_NAME_STRING,
+ TRUE,
+ gShellFUpdateHiiHandle,
+ STRING_TOKEN (STR_GET_HELP_FUPDATE)
+ );
+
+ if (EFI_ERROR(Status)) {
+ Print (L"%s: Error while registering command\n", CMD_NAME_STRING);
+ return SHELL_ABORTED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+ShellFUpdateCommandDestructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+
+ if (gShellFUpdateHiiHandle != NULL) {
+ HiiRemovePackages (gShellFUpdateHiiHandle);
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/Silicon/Marvell/Applications/FirmwareUpdate/FUpdate.inf b/Silicon/Marvell/Applications/FirmwareUpdate/FUpdate.inf
new file mode 100644
index 0000000000..69ee0f8308
--- /dev/null
+++ b/Silicon/Marvell/Applications/FirmwareUpdate/FUpdate.inf
@@ -0,0 +1,73 @@
+#
+# 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 = 0x00010019
+ BASE_NAME = UefiShellFUpdateCommandLib
+ FILE_GUID = 470292b2-926b-4ed8-8080-be7a260db627
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 0.1
+ LIBRARY_CLASS = NULL|UEFI_APPLICATION UEFI_DRIVER
+ CONSTRUCTOR = ShellFUpdateCommandConstructor
+ DESTRUCTOR = ShellFUpdateCommandDestructor
+
+[Sources]
+ FUpdate.c
+ FUpdate.uni
+
+[Packages]
+ EmbeddedPkg/EmbeddedPkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ MdePkg/MdePkg.dec
+ Silicon/Marvell/Marvell.dec
+ ShellPkg/ShellPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ FileHandleLib
+ HiiLib
+ MemoryAllocationLib
+ PcdLib
+ ShellCommandLib
+ ShellLib
+ UefiBootServicesTableLib
+ UefiLib
+ UefiLib
+ UefiRuntimeServicesTableLib
+
+[Protocols]
+ gMarvellSpiFlashProtocolGuid
+ gMarvellSpiMasterProtocolGuid
+
+[Guids]
+ gShellFUpdateHiiGuid
diff --git a/Silicon/Marvell/Applications/FirmwareUpdate/FUpdate.uni b/Silicon/Marvell/Applications/FirmwareUpdate/FUpdate.uni
new file mode 100644
index 0000000000..146f624737
--- /dev/null
+++ b/Silicon/Marvell/Applications/FirmwareUpdate/FUpdate.uni
Binary files differ
diff --git a/Silicon/Marvell/Applications/SpiTool/SpiFlashCmd.c b/Silicon/Marvell/Applications/SpiTool/SpiFlashCmd.c
new file mode 100644
index 0000000000..cf91581dcf
--- /dev/null
+++ b/Silicon/Marvell/Applications/SpiTool/SpiFlashCmd.c
@@ -0,0 +1,516 @@
+/*******************************************************************************
+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 SPI_DEVICE *mSlave;
+
+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;
+
+ Status = SpiFlashProtocol->ReadId (Slave, FALSE);
+ if (EFI_ERROR (Status)) {
+ return SHELL_ABORTED;
+ }
+
+ Status = SpiFlashProtocol->Init (SpiFlashProtocol, Slave);
+ if (EFI_ERROR (Status)) {
+ Print (L"sf: Cannot initialize flash device\n");
+ return SHELL_ABORTED;
+ }
+
+ InitFlag = 0;
+
+ return SHELL_SUCCESS;
+}
+
+SHELL_STATUS
+EFIAPI
+ShellCommandRunSpiFlash (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+EFI_STATUS Status;
+ LIST_ENTRY *CheckPackage;
+ EFI_PHYSICAL_ADDRESS Address = 0, Offset = 0;
+ SHELL_FILE_HANDLE FileHandle = NULL;
+ UINTN ByteCount, I;
+ UINT64 FileSize;
+ 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;
+ UINT8 Mode, Cs;
+
+ 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;
+ }
+ }
+
+ Mode = PcdGet32 (PcdSpiFlashMode);
+ Cs = PcdGet32 (PcdSpiFlashCs);
+
+ // Setup new spi device
+ mSlave = SpiMasterProtocol->SetupDevice (SpiMasterProtocol, mSlave, Cs, Mode);
+ if (mSlave == NULL) {
+ Print(L"sf: Cannot allocate SPI device!\n");
+ return SHELL_ABORTED;
+ }
+
+ switch (Flag) {
+ case PROBE:
+ // Probe spi bus
+ Status = FlashProbe (mSlave);
+ if (EFI_ERROR(Status)) {
+ // No supported spi flash detected
+ SpiMasterProtocol->FreeDevice(mSlave);
+ mSlave = NULL;
+ 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 *)(UINTN)Address;
+ if (FileFlag) {
+ Buffer = FileBuffer;
+ }
+
+ switch (Flag) {
+ case READ:
+ case READ_FILE:
+ Status = SpiFlashProtocol->Read (mSlave, Offset, ByteCount, Buffer);
+ break;
+ case ERASE:
+ Status = SpiFlashProtocol->Erase (mSlave, Offset, ByteCount);
+ break;
+ case WRITE:
+ case WRITE_FILE:
+ Status = SpiFlashProtocol->Write (mSlave, Offset, ByteCount, Buffer);
+ break;
+ case UPDATE:
+ case UPDATE_FILE:
+ Status = SpiFlashProtocol->Update (mSlave, Offset, ByteCount, Buffer);
+ break;
+ }
+
+ 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/Silicon/Marvell/Applications/SpiTool/SpiFlashCmd.inf b/Silicon/Marvell/Applications/SpiTool/SpiFlashCmd.inf
new file mode 100644
index 0000000000..647ab506b3
--- /dev/null
+++ b/Silicon/Marvell/Applications/SpiTool/SpiFlashCmd.inf
@@ -0,0 +1,77 @@
+#
+# 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]
+ EmbeddedPkg/EmbeddedPkg.dec
+ MdePkg/MdePkg.dec
+ ShellPkg/ShellPkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ Silicon/Marvell/Marvell.dec
+
+[LibraryClasses]
+ UefiLib
+ UefiBootServicesTableLib
+ MemoryAllocationLib
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ ShellCommandLib
+ ShellLib
+ UefiLib
+ UefiRuntimeServicesTableLib
+ PcdLib
+ HiiLib
+ FileHandleLib
+
+[Pcd]
+ gMarvellTokenSpaceGuid.PcdSpiFlashCs
+ gMarvellTokenSpaceGuid.PcdSpiFlashMode
+
+[Protocols]
+ gMarvellSpiFlashProtocolGuid
+ gMarvellSpiMasterProtocolGuid
+
+[Guids]
+ gShellSfHiiGuid
diff --git a/Silicon/Marvell/Applications/SpiTool/SpiFlashCmd.uni b/Silicon/Marvell/Applications/SpiTool/SpiFlashCmd.uni
new file mode 100644
index 0000000000..3f25663ed7
--- /dev/null
+++ b/Silicon/Marvell/Applications/SpiTool/SpiFlashCmd.uni
Binary files differ