Hello,
Here's 6th version of the support. It's rebased on top of newest master branch and comprise fixes from the latest review.
Patches are also available in the github: https://github.com/MarvellEmbeddedProcessors/edk2-open-platform/commits/opp-...
Any comments or remarks would be welcome.
Best regards, Marcin
Changelog: v5 -> v6 * Initial support - Enable compilation after ArmMmuLib was added to edk2 - Remove commented-out line - Enable up to 64MB RamDisk space for all Armada platforms - Move adding "-fno-unwind-tables" build flag to a separate patch and add explanation for this change * I2C - Change MvI2cDevicePathProtocol to STATIC in MvI2cDxe.c - Generate new I2C_GUID - Move I2C_GUID to header files and extend existing FIXME comment * Fupdate - Add FIXME note over including relative path from edk2. It was needed after fixing regression by replacing ShellExecute with RunShellCommand
v4 -> v5
* Add ParsePcdLib - Library created in order to parse PCD strings - it makes support for multi-controller easier to implement * I2c - Introduce multi-bus support - Remove comments regarding GUID-slave address dependency - Add FIXME comment about no-restart dual definition * eeprom command - Enable selecting I2C bus - Add FIXME comment about no-restart dual definition * Spi - Fix writing procedure - Rename protocol to MARVELL_SPI_MASTER_PROTOCOL * General - Remove commented-out, unused lines
v3 -> v4
* Update license messages - Unify - Add "Based on" statement were needed - Wrap every message at 80 characters - Add Marvell copyrights * Fix namings - All protocol/file names updated as suggested in review * Clean-up - Remove unneded blank lines and spaces - Fix typos * Add "Reviewed by" for currently accepted patches * Add support for new platform - Armada70x0 - Remove support for old platforms Apn806 and Armada7040_rz - Armada70x0 is based on Armada7040_rz with silicone fixes and improvements - No changes on drivers/libraries caused by this change - Update commit logs in whole tree * MppLib - Fix issue with writing to uninitialized memory * I2c and eeprom command - Remove dependency on BdsLibConnectAll call - I2c stack is connected only if eeprom command is executed and only in case it wasn't done before - gBS->ConnectController() used * BdsLib - Remove import of BdsLib - After rebase on top of new edk2, extra BdsLibConnectAll call isn't necessary (actually for now no BdsLibConnectAll is needed at all for our platform support) * sf command - Remove inclusion of relative path - Necessary macro now defined in globally exported file * RamDisk driver - Drop patch with this feature - As long as there is no possibility to format RamDisk with FAT, driver is not useful on Armada70x0 * fupdate command - Fix issue with "bad checksum"
v2 -> v3
* Decrease binary size * Fupdate command - Remove regression - replace ShellExecute with RunShellCommand - Improve error paths * Add proper DEBUG library and change error print levels
v1 -> v2
* Fix "may be used uninitialized" variables issue, branch compiles both with DEBUG and RELEASE flags * Remove I2C_FLAG_NORESTART dependency - replace it with local definition * Remove Marvell UART Library: - DW8250 IP has programming interface compatible with NS-16550. Since in edk2 there is support for 16550, internal library is unnecessary. - /Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf is used instead * RamDisk driver: - Remove old driver imported from EFI TOOLKIT 2.0 - Replace it with new MdeModulePkg/Universal/Disk/RamDiskDxe from edk2 - Lack of FAT formatting issue emerged * Add explicit dependency on IoLib in Drivers/Spi/SpiDxe.inf * Add poster's "Signed-off-by" registry to every commit message * Move to 05.04.2016 HEAD of edk2/master - Update CpuExceptionHandlerLib within OPP.
Bartosz Szczepanek (3): Drivers/I2c: Create MvI2cDxe driver Drivers/I2c: Add MvEeprom driver Aplications/Eeprom: Add 'eeprom' command to shell
Haim Boot (1): Platforms/Marvell: Enable compilation with aarch64-linux-gnueabi toolchain
Jan Dąbroś (17): Platforms/Marvell: Create MppLib Platforms/Marvell: Armada: Enable MppLib on Armada70x0 platform Platforms/Marvell: Create ParsePcdLib Platforms/Marvell: Enable ParsePcdLib for Armada70x0 platform Platforms/Marvell: Enable I2C driver on Armada70x0 platform Plaforms/Marvell: Enable EEPROM driver on Armada70x0 platform Platforms/Marvell: Enable 'eeprom' command on Armada70x0 platform Platforms/Marvell: Add MARVELL_SPI_MASTER_PROTOCOL Drivers/Spi: Add Spi master driver Platforms/Marvell: Enable Spi master driver for Armada70x0 platform Platforms/Marvell: Add MARVELL_SPI_FLASH_PROTOCOL Drivers/Spi: Implement Spi flash driver Platforms/Marvell: Enable Spi flash driver for Armada70x0 platform Applications/SpiTool: Add 'sf' command utility Platforms/Marvell: Enable 'sf' command on Armada70x0 platform Applications/FirmwareUpdate: Add 'fupdate' comand to shell Platforms/Marvell: Enable 'fupdate' command on Armada70x0 platform
Yehuda Yitschak (2): Platforms/Marvell: Add initial support for Armada70x0 SOC lib Platforms/Marvell: Add support for Armada70x0 platform
Applications/EepromCmd/EepromCmd.c | 397 +++++++++++ Applications/EepromCmd/EepromCmd.inf | 71 ++ Applications/EepromCmd/EepromCmd.uni | Bin 0 -> 6816 bytes Applications/FirmwareUpdate/FUpdate.c | 448 +++++++++++++ Applications/FirmwareUpdate/FUpdate.inf | 68 ++ Applications/FirmwareUpdate/FUpdate.uni | Bin 0 -> 5838 bytes Applications/SpiTool/SpiFlashCmd.c | 526 +++++++++++++++ Applications/SpiTool/SpiFlashCmd.inf | 75 +++ Applications/SpiTool/SpiFlashCmd.uni | Bin 0 -> 7216 bytes Documentation/Marvell/Drivers/EepromDriver.txt | 96 +++ Documentation/Marvell/Drivers/I2cDriver.txt | 64 ++ Documentation/Marvell/Drivers/SpiDriver.txt | 116 ++++ Documentation/Marvell/PortingGuide/I2c.txt | 20 + Documentation/Marvell/PortingGuide/Mpp.txt | 48 ++ Documentation/Marvell/PortingGuide/Spi.txt | 15 + Documentation/Marvell/PortingGuide/SpiFlash.txt | 23 + Drivers/I2c/Devices/MvEeprom/MvEeprom.c | 292 ++++++++ Drivers/I2c/Devices/MvEeprom/MvEeprom.h | 103 +++ Drivers/I2c/Devices/MvEeprom/MvEeprom.inf | 70 ++ Drivers/I2c/MvI2cDxe/MvI2cDxe.c | 739 +++++++++++++++++++++ Drivers/I2c/MvI2cDxe/MvI2cDxe.h | 269 ++++++++ Drivers/I2c/MvI2cDxe/MvI2cDxe.inf | 75 +++ Drivers/Spi/Devices/MvSpiFlash.c | 531 +++++++++++++++ Drivers/Spi/Devices/MvSpiFlash.h | 132 ++++ Drivers/Spi/Devices/MvSpiFlash.inf | 67 ++ Drivers/Spi/MvSpiDxe.c | 379 +++++++++++ Drivers/Spi/MvSpiDxe.h | 145 ++++ Drivers/Spi/MvSpiDxe.inf | 66 ++ Platforms/Marvell/Armada/Armada.dsc.inc | 453 +++++++++++++ Platforms/Marvell/Armada/Armada70x0.dsc | 97 +++ Platforms/Marvell/Armada/Armada70x0.fdf | 270 ++++++++ .../Armada70x0Lib/AArch64/ArmPlatformHelper.S | 66 ++ .../Armada/Library/Armada70x0Lib/Armada70x0Lib.c | 155 +++++ .../Armada/Library/Armada70x0Lib/Armada70x0Lib.inf | 69 ++ .../Library/Armada70x0Lib/Armada70x0LibMem.c | 93 +++ Platforms/Marvell/Include/Library/MppLib.h | 42 ++ Platforms/Marvell/Include/Library/ParsePcdLib.h | 46 ++ Platforms/Marvell/Include/Protocol/Eeprom.h | 60 ++ Platforms/Marvell/Include/Protocol/Spi.h | 105 +++ Platforms/Marvell/Include/Protocol/SpiFlash.h | 113 ++++ Platforms/Marvell/Library/MppLib/MppLib.c | 163 +++++ Platforms/Marvell/Library/MppLib/MppLib.inf | 107 +++ .../Marvell/Library/ParsePcdLib/ParsePcdLib.c | 228 +++++++ .../Marvell/Library/ParsePcdLib/ParsePcdLib.inf | 50 ++ Platforms/Marvell/Marvell.dec | 136 ++++ 45 files changed, 7088 insertions(+) create mode 100644 Applications/EepromCmd/EepromCmd.c create mode 100644 Applications/EepromCmd/EepromCmd.inf create mode 100644 Applications/EepromCmd/EepromCmd.uni create mode 100644 Applications/FirmwareUpdate/FUpdate.c create mode 100644 Applications/FirmwareUpdate/FUpdate.inf create mode 100644 Applications/FirmwareUpdate/FUpdate.uni create mode 100644 Applications/SpiTool/SpiFlashCmd.c create mode 100644 Applications/SpiTool/SpiFlashCmd.inf create mode 100644 Applications/SpiTool/SpiFlashCmd.uni create mode 100644 Documentation/Marvell/Drivers/EepromDriver.txt create mode 100644 Documentation/Marvell/Drivers/I2cDriver.txt create mode 100644 Documentation/Marvell/Drivers/SpiDriver.txt create mode 100644 Documentation/Marvell/PortingGuide/I2c.txt create mode 100644 Documentation/Marvell/PortingGuide/Mpp.txt create mode 100644 Documentation/Marvell/PortingGuide/Spi.txt create mode 100644 Documentation/Marvell/PortingGuide/SpiFlash.txt create mode 100644 Drivers/I2c/Devices/MvEeprom/MvEeprom.c create mode 100644 Drivers/I2c/Devices/MvEeprom/MvEeprom.h create mode 100644 Drivers/I2c/Devices/MvEeprom/MvEeprom.inf create mode 100755 Drivers/I2c/MvI2cDxe/MvI2cDxe.c create mode 100644 Drivers/I2c/MvI2cDxe/MvI2cDxe.h create mode 100755 Drivers/I2c/MvI2cDxe/MvI2cDxe.inf create mode 100755 Drivers/Spi/Devices/MvSpiFlash.c create mode 100755 Drivers/Spi/Devices/MvSpiFlash.h create mode 100644 Drivers/Spi/Devices/MvSpiFlash.inf create mode 100755 Drivers/Spi/MvSpiDxe.c create mode 100644 Drivers/Spi/MvSpiDxe.h create mode 100644 Drivers/Spi/MvSpiDxe.inf create mode 100644 Platforms/Marvell/Armada/Armada.dsc.inc create mode 100644 Platforms/Marvell/Armada/Armada70x0.dsc create mode 100644 Platforms/Marvell/Armada/Armada70x0.fdf create mode 100644 Platforms/Marvell/Armada/Library/Armada70x0Lib/AArch64/ArmPlatformHelper.S create mode 100644 Platforms/Marvell/Armada/Library/Armada70x0Lib/Armada70x0Lib.c create mode 100644 Platforms/Marvell/Armada/Library/Armada70x0Lib/Armada70x0Lib.inf create mode 100644 Platforms/Marvell/Armada/Library/Armada70x0Lib/Armada70x0LibMem.c create mode 100644 Platforms/Marvell/Include/Library/MppLib.h create mode 100644 Platforms/Marvell/Include/Library/ParsePcdLib.h create mode 100644 Platforms/Marvell/Include/Protocol/Eeprom.h create mode 100644 Platforms/Marvell/Include/Protocol/Spi.h create mode 100644 Platforms/Marvell/Include/Protocol/SpiFlash.h create mode 100644 Platforms/Marvell/Library/MppLib/MppLib.c create mode 100644 Platforms/Marvell/Library/MppLib/MppLib.inf create mode 100644 Platforms/Marvell/Library/ParsePcdLib/ParsePcdLib.c create mode 100644 Platforms/Marvell/Library/ParsePcdLib/ParsePcdLib.inf create mode 100644 Platforms/Marvell/Marvell.dec
From: Yehuda Yitschak yehuday@marvell.com
This patch adds initial support for Armada70x0 SoC's initialization. It implements empty mandatory hooks which are currently mostly empty except for Memory mapping information.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Yehuda Yitschak yehuday@marvell.com Signed-off-by: Marcin Wojtas mw@semihalf.com Reviewed-by: Leif Lindholm leif.lindholm@linaro.org --- .../Armada70x0Lib/AArch64/ArmPlatformHelper.S | 66 +++++++++ .../Armada/Library/Armada70x0Lib/Armada70x0Lib.c | 153 +++++++++++++++++++++ .../Armada/Library/Armada70x0Lib/Armada70x0Lib.inf | 67 +++++++++ .../Library/Armada70x0Lib/Armada70x0LibMem.c | 93 +++++++++++++ 4 files changed, 379 insertions(+) create mode 100644 Platforms/Marvell/Armada/Library/Armada70x0Lib/AArch64/ArmPlatformHelper.S create mode 100644 Platforms/Marvell/Armada/Library/Armada70x0Lib/Armada70x0Lib.c create mode 100644 Platforms/Marvell/Armada/Library/Armada70x0Lib/Armada70x0Lib.inf create mode 100644 Platforms/Marvell/Armada/Library/Armada70x0Lib/Armada70x0LibMem.c
diff --git a/Platforms/Marvell/Armada/Library/Armada70x0Lib/AArch64/ArmPlatformHelper.S b/Platforms/Marvell/Armada/Library/Armada70x0Lib/AArch64/ArmPlatformHelper.S new file mode 100644 index 0000000..4ad435c --- /dev/null +++ b/Platforms/Marvell/Armada/Library/Armada70x0Lib/AArch64/ArmPlatformHelper.S @@ -0,0 +1,66 @@ +//Based on ArmPlatformPkg/Library/ArmPlatformLibNull/AArch64/ArmPlatformHelper.S +// +// Copyright (c) 2012-2013, ARM Limited. All rights reserved. +// Copyright (c) 2016, Marvell. 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 <AsmMacroIoLibV8.h> +#include <Library/ArmLib.h> + +.text +.align 2 + +GCC_ASM_EXPORT(ArmPlatformPeiBootAction) +GCC_ASM_EXPORT(ArmPlatformGetCorePosition) +GCC_ASM_EXPORT(ArmPlatformGetPrimaryCoreMpId) +GCC_ASM_EXPORT(ArmPlatformIsPrimaryCore) + +GCC_ASM_IMPORT(_gPcd_FixedAtBuild_PcdArmPrimaryCore) +GCC_ASM_IMPORT(_gPcd_FixedAtBuild_PcdArmPrimaryCoreMask) + +ASM_PFX(ArmPlatformPeiBootAction): + ret + +//UINTN +//ArmPlatformGetCorePosition ( +// IN UINTN MpId +// ); +// With this function: CorePos = (ClusterId * 4) + CoreId +ASM_PFX(ArmPlatformGetCorePosition): + and x1, x0, #ARM_CORE_MASK + and x0, x0, #ARM_CLUSTER_MASK + add x0, x1, x0, LSR #6 + ret + +//UINTN +//ArmPlatformGetPrimaryCoreMpId ( +// VOID +// ); +ASM_PFX(ArmPlatformGetPrimaryCoreMpId): + LoadConstantToReg (_gPcd_FixedAtBuild_PcdArmPrimaryCore, x0) + ldrh w0, [x0] + ret + +//UINTN +//ArmPlatformIsPrimaryCore ( +// IN UINTN MpId +// ); +ASM_PFX(ArmPlatformIsPrimaryCore): + LoadConstantToReg (_gPcd_FixedAtBuild_PcdArmPrimaryCoreMask, x1) + ldrh w1, [x1] + and x0, x0, x1 + LoadConstantToReg (_gPcd_FixedAtBuild_PcdArmPrimaryCore, x1) + ldrh w1, [x1] + cmp w0, w1 + mov x0, #1 + mov x1, #0 + csel x0, x0, x1, eq + ret diff --git a/Platforms/Marvell/Armada/Library/Armada70x0Lib/Armada70x0Lib.c b/Platforms/Marvell/Armada/Library/Armada70x0Lib/Armada70x0Lib.c new file mode 100644 index 0000000..8609700 --- /dev/null +++ b/Platforms/Marvell/Armada/Library/Armada70x0Lib/Armada70x0Lib.c @@ -0,0 +1,153 @@ +/**Based on ArmPlatformPkg/Library/ArmPlatformLibNull/ArmPlatformLibNull.c +* +* Copyright (c) 2011-2012, ARM Limited. All rights reserved. +* Copyright (c) 2016, Marvell International Ltd. 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 <Library/ArmLib.h> +#include <Library/ArmPlatformLib.h> +#include <Ppi/ArmMpCoreInfo.h> + + +ARM_CORE_INFO mArmada7040MpCoreInfoTable[] = { + { + // Cluster 0, Core 0 + 0x0, 0x0, + + // MP Core MailBox Set/Get/Clear Addresses and Clear Value + (EFI_PHYSICAL_ADDRESS)0, + (EFI_PHYSICAL_ADDRESS)0, + (EFI_PHYSICAL_ADDRESS)0, + (UINT64)0xFFFFFFFF + }, + { + // Cluster 0, Core 1 + 0x0, 0x1, + + // MP Core MailBox Set/Get/Clear Addresses and Clear Value + (EFI_PHYSICAL_ADDRESS)0, + (EFI_PHYSICAL_ADDRESS)0, + (EFI_PHYSICAL_ADDRESS)0, + (UINT64)0xFFFFFFFF + }, + { + // Cluster 0, Core 2 + 0x0, 0x2, + + // MP Core MailBox Set/Get/Clear Addresses and Clear Value + (EFI_PHYSICAL_ADDRESS)0, + (EFI_PHYSICAL_ADDRESS)0, + (EFI_PHYSICAL_ADDRESS)0, + (UINT64)0xFFFFFFFF + }, + { + // Cluster 0, Core 3 + 0x0, 0x3, + + // MP Core MailBox Set/Get/Clear Addresses and Clear Value + (EFI_PHYSICAL_ADDRESS)0, + (EFI_PHYSICAL_ADDRESS)0, + (EFI_PHYSICAL_ADDRESS)0, + (UINT64)0xFFFFFFFF + } +}; + +/** + Return the current Boot Mode + + This function returns the boot reason on the platform + +**/ +EFI_BOOT_MODE +ArmPlatformGetBootMode ( + VOID + ) +{ + return BOOT_WITH_FULL_CONFIGURATION; +} + +/** + Initialize controllers that must setup in the normal world + + This function is called by the ArmPlatformPkg/PrePi or ArmPlatformPkg/PlatformPei + in the PEI phase. + +**/ +RETURN_STATUS +ArmPlatformInitialize ( + IN UINTN MpId + ) +{ + if (!ArmPlatformIsPrimaryCore (MpId)) { + return RETURN_SUCCESS; + } + + //TODO: Add basic platfrom initialization + + return RETURN_SUCCESS; +} + +/** + Initialize the system (or sometimes called permanent) memory + + This memory is generally represented by the DRAM. + +**/ +VOID +ArmPlatformInitializeSystemMemory ( + VOID + ) +{ + //TODO: Initialize DRAM controller here +} + +EFI_STATUS +PrePeiCoreGetMpCoreInfo ( + OUT UINTN *CoreCount, + OUT ARM_CORE_INFO **ArmCoreTable + ) +{ + if (ArmIsMpCore()) { + *CoreCount = sizeof(mArmada7040MpCoreInfoTable) / sizeof(ARM_CORE_INFO); + *ArmCoreTable = mArmada7040MpCoreInfoTable; + return EFI_SUCCESS; + } else { + return EFI_UNSUPPORTED; + } +} + +ARM_MP_CORE_INFO_PPI mMpCoreInfoPpi = { PrePeiCoreGetMpCoreInfo }; + +EFI_PEI_PPI_DESCRIPTOR gPlatformPpiTable[] = { + { + EFI_PEI_PPI_DESCRIPTOR_PPI, + &gArmMpCoreInfoPpiGuid, + &mMpCoreInfoPpi + } +}; + +VOID +ArmPlatformGetPlatformPpiList ( + OUT UINTN *PpiListSize, + OUT EFI_PEI_PPI_DESCRIPTOR **PpiList + ) +{ + if (ArmIsMpCore()) { + *PpiListSize = sizeof(gPlatformPpiTable); + *PpiList = gPlatformPpiTable; + } else { + *PpiListSize = 0; + *PpiList = NULL; + } +} + + diff --git a/Platforms/Marvell/Armada/Library/Armada70x0Lib/Armada70x0Lib.inf b/Platforms/Marvell/Armada/Library/Armada70x0Lib/Armada70x0Lib.inf new file mode 100644 index 0000000..2e2120e --- /dev/null +++ b/Platforms/Marvell/Armada/Library/Armada70x0Lib/Armada70x0Lib.inf @@ -0,0 +1,67 @@ +# 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. +# + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = Armada7040Lib + FILE_GUID = 3f29b642-4a49-4dfd-8f4a-205dd38432bb + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = ArmPlatformLib + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + ArmPkg/ArmPkg.dec + ArmPlatformPkg/ArmPlatformPkg.dec + +[LibraryClasses] + ArmLib + DebugLib + MemoryAllocationLib + +[Sources.common] + Armada70x0Lib.c + Armada70x0LibMem.c + +[Sources.AArch64] + AArch64/ArmPlatformHelper.S + +[FixedPcd] + gArmTokenSpaceGuid.PcdSystemMemoryBase + gArmTokenSpaceGuid.PcdSystemMemorySize + + gArmTokenSpaceGuid.PcdArmPrimaryCoreMask + gArmTokenSpaceGuid.PcdArmPrimaryCore + +[Ppis] + gArmMpCoreInfoPpiGuid diff --git a/Platforms/Marvell/Armada/Library/Armada70x0Lib/Armada70x0LibMem.c b/Platforms/Marvell/Armada/Library/Armada70x0Lib/Armada70x0LibMem.c new file mode 100644 index 0000000..74c9956 --- /dev/null +++ b/Platforms/Marvell/Armada/Library/Armada70x0Lib/Armada70x0LibMem.c @@ -0,0 +1,93 @@ +/******************************************************************************* +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 <Base.h> +#include <Library/ArmPlatformLib.h> +#include <Library/DebugLib.h> +#include <Library/MemoryAllocationLib.h> + +// The total number of descriptors, including the final "end-of-table" descriptor. +#define MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS 16 + +// DDR attributes +#define DDR_ATTRIBUTES_CACHED ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_BACK +#define DDR_ATTRIBUTES_UNCACHED ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED + +/** + Return the Virtual Memory Map of your platform + + This Virtual Memory Map is used by MemoryInitPei Module to initialize the MMU on your platform. + + @param[out] VirtualMemoryMap Array of ARM_MEMORY_REGION_DESCRIPTOR describing a Physical-to- + Virtual Memory mapping. This array must be ended by a zero-filled + entry + +**/ +VOID +ArmPlatformGetVirtualMemoryMap ( + IN ARM_MEMORY_REGION_DESCRIPTOR** VirtualMemoryMap + ) +{ + ARM_MEMORY_REGION_DESCRIPTOR *VirtualMemoryTable; + UINTN Index = 0; + + ASSERT (VirtualMemoryMap != NULL); + + VirtualMemoryTable = (ARM_MEMORY_REGION_DESCRIPTOR*)AllocatePages(EFI_SIZE_TO_PAGES (sizeof(ARM_MEMORY_REGION_DESCRIPTOR) * MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS)); + if (VirtualMemoryTable == NULL) { + return; + } + + // DDR + VirtualMemoryTable[Index].PhysicalBase = PcdGet64 (PcdSystemMemoryBase); + VirtualMemoryTable[Index].VirtualBase = PcdGet64 (PcdSystemMemoryBase); + VirtualMemoryTable[Index].Length = PcdGet64 (PcdSystemMemorySize); + VirtualMemoryTable[Index].Attributes = DDR_ATTRIBUTES_CACHED; + + // Configuration space 0xF000_0000 - 0xFFFF_FFFF + VirtualMemoryTable[++Index].PhysicalBase = 0xF0000000; + VirtualMemoryTable[Index].VirtualBase = 0xF0000000; + VirtualMemoryTable[Index].Length = 0x10000000; + VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; + + // End of Table + VirtualMemoryTable[++Index].PhysicalBase = 0; + VirtualMemoryTable[Index].VirtualBase = 0; + VirtualMemoryTable[Index].Length = 0; + VirtualMemoryTable[Index].Attributes = 0; + + ASSERT((Index + 1) <= MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS); + + *VirtualMemoryMap = VirtualMemoryTable; +}
From: Yehuda Yitschak yehuday@marvell.com
This patch add initial support for Armada70x0 platform. It includes Armada.dsc.inc and uses Armada70x0.fdf files, which are created with the aim of support for new boards. Code currently supports: - GICv2 - ARM architected timer - ARM watchdog timer - UART port
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Yehuda Yitschak yehuday@marvell.com Signed-off-by: Jan Dabros jsd@semihalf.com Signed-off-by: Marcin Wojtas mw@semihalf.com --- Platforms/Marvell/Armada/Armada.dsc.inc | 437 ++++++++++++++++++++++++++++++++ Platforms/Marvell/Armada/Armada70x0.dsc | 48 ++++ Platforms/Marvell/Armada/Armada70x0.fdf | 265 +++++++++++++++++++ 3 files changed, 750 insertions(+) create mode 100644 Platforms/Marvell/Armada/Armada.dsc.inc create mode 100644 Platforms/Marvell/Armada/Armada70x0.dsc create mode 100644 Platforms/Marvell/Armada/Armada70x0.fdf
diff --git a/Platforms/Marvell/Armada/Armada.dsc.inc b/Platforms/Marvell/Armada/Armada.dsc.inc new file mode 100644 index 0000000..530b867 --- /dev/null +++ b/Platforms/Marvell/Armada/Armada.dsc.inc @@ -0,0 +1,437 @@ +#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. +# +[LibraryClasses.common] + ArmPlatformLib|OpenPlatformPkg/Platforms/Marvell/Armada/Library/Armada70x0Lib/Armada70x0Lib.inf + + DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf + UncachedMemoryAllocationLib|ArmPkg/Library/UncachedMemoryAllocationLib/UncachedMemoryAllocationLib.inf + DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf + +# Basic utility libraries + BaseLib|MdePkg/Library/BaseLib/BaseLib.inf + SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf + PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf + PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf + PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf + PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf + IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf + UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf + CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf + PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf + PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf + +# Basic UEFI services libraries + UefiLib|MdePkg/Library/UefiLib/UefiLib.inf + HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf + UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf + DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf + UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf + DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf + UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf + UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf + HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf + UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf + UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf + + # Assume everything is fixed at build. do not use runtime PCD feature + PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf + + # 1/123 faster than Stm or Vstm version + BaseMemoryLib|ArmPkg/Library/BaseMemoryLibStm/BaseMemoryLibStm.inf + + # ARM Architectural Libraries + CacheMaintenanceLib|ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf + DefaultExceptionHandlerLib|ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf + CpuExceptionHandlerLib|ArmPkg/Library/ArmExceptionLib/ArmExceptionLib.inf + ArmDisassemblerLib|ArmPkg/Library/ArmDisassemblerLib/ArmDisassemblerLib.inf + DmaLib|ArmPkg/Library/ArmDmaLib/ArmDmaLib.inf + ArmGicLib|ArmPkg/Drivers/ArmGic/ArmGicLib.inf + ArmGicArchLib|ArmPkg/Library/ArmGicArchLib/ArmGicArchLib.inf + ArmPlatformStackLib|ArmPlatformPkg/Library/ArmPlatformStackLib/ArmPlatformStackLib.inf + ArmSmcLib|ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf + TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf + + # Serial port libraries + SerialPortLib|MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf + PlatformHookLib|MdeModulePkg/Library/BasePlatformHookLibNull/BasePlatformHookLibNull.inf + + # Reset and Time libraries + EfiResetSystemLib|EmbeddedPkg/Library/TemplateResetSystemLib/TemplateResetSystemLib.inf + RealTimeClockLib|EmbeddedPkg/Library/TemplateRealTimeClockLib/TemplateRealTimeClockLib.inf + + # Networking Requirements for ArmPlatformPkg/Bds + NetLib|MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf + + # These libraries are used by the dynamic EFI Shell commands + ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf + FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf + SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf + + # EBL Related Libraries + EblCmdLib|ArmPlatformPkg/Library/EblCmdLib/EblCmdLib.inf + EfiFileLib|EmbeddedPkg/Library/EfiFileLib/EfiFileLib.inf + EblAddExternalCommandLib|EmbeddedPkg/Library/EblAddExternalCommandLib/EblAddExternalCommandLib.inf + EblNetworkLib|EmbeddedPkg/Library/EblNetworkLib/EblNetworkLib.inf + + # + # Uncomment (and comment out the next line) For RealView Debugger. The Standard IO window + # in the debugger will show load and unload commands for symbols. You can cut and paste this + # into the command window to load symbols. We should be able to use a script to do this, but + # the version of RVD I have does not support scripts accessing system memory. + # + #PeCoffExtraActionLib|ArmPkg/Library/RvdPeCoffExtraActionLib/RvdPeCoffExtraActionLib.inf + PeCoffExtraActionLib|ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.inf + #PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf + + DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf + DebugAgentTimerLib|EmbeddedPkg/Library/DebugAgentTimerLibNull/DebugAgentTimerLibNull.inf + # SemihostLib|ArmPkg/Library/SemihostLib/SemihostLib.inf + + # BDS Libraries + BdsLib|ArmPkg/Library/BdsLib/BdsLib.inf + CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf + GenericBdsLib|IntelFrameworkModulePkg/Library/GenericBdsLib/GenericBdsLib.inf + PlatformBdsLib|ArmPlatformPkg/Library/PlatformIntelBdsLib/PlatformIntelBdsLib.inf + CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf + FdtLib|EmbeddedPkg/Library/FdtLib/FdtLib.inf + +[LibraryClasses.AARCH64] + ArmLib|ArmPkg/Library/ArmLib/AArch64/AArch64Lib.inf + ArmMmuLib|ArmPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf + ArmCpuLib|ArmPkg/Drivers/ArmCpuLib/ArmCortexAEMv8Lib/ArmCortexAEMv8Lib.inf + ArmGenericTimerCounterLib|ArmPkg/Library/ArmGenericTimerPhyCounterLib/ArmGenericTimerPhyCounterLib.inf + +[LibraryClasses.common.SEC] + ArmLib|ArmPkg/Library/ArmLib/AArch64/AArch64LibSec.inf + + DebugAgentLib|ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.inf + DefaultExceptionHandlerLib|ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLibBase.inf + + PrePiLib|EmbeddedPkg/Library/PrePiLib/PrePiLib.inf + ExtractGuidedSectionLib|EmbeddedPkg/Library/PrePiExtractGuidedSectionLib/PrePiExtractGuidedSectionLib.inf + LzmaDecompressLib|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf + MemoryAllocationLib|EmbeddedPkg/Library/PrePiMemoryAllocationLib/PrePiMemoryAllocationLib.inf + HobLib|EmbeddedPkg/Library/PrePiHobLib/PrePiHobLib.inf + PrePiHobListPointerLib|ArmPlatformPkg/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.inf + PlatformPeiLib|ArmPlatformPkg/PlatformPei/PlatformPeiLib.inf + ArmGicArchLib|ArmPkg/Library/ArmGicArchSecLib/ArmGicArchSecLib.inf + +[LibraryClasses.common.SEC, LibraryClasses.common.PEIM] + MemoryInitPeiLib|ArmPlatformPkg/MemoryInitPei/MemoryInitPeiLib.inf + +[LibraryClasses.common.DXE_CORE] + HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf + MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf + DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf + ReportStatusCodeLib|IntelFrameworkModulePkg/Library/DxeReportStatusCodeLibFramework/DxeReportStatusCodeLib.inf + ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf + UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf + DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf + PerformanceLib|MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.inf + +[LibraryClasses.common.DXE_DRIVER] + ReportStatusCodeLib|IntelFrameworkModulePkg/Library/DxeReportStatusCodeLibFramework/DxeReportStatusCodeLib.inf + DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf + SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf + PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf + MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf + +[LibraryClasses.common.UEFI_APPLICATION] + UefiDecompressLib|IntelFrameworkModulePkg/Library/BaseUefiTianoCustomDecompressLib/BaseUefiTianoCustomDecompressLib.inf + PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf + MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf + HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf + +[LibraryClasses.common.UEFI_DRIVER] + ReportStatusCodeLib|IntelFrameworkModulePkg/Library/DxeReportStatusCodeLibFramework/DxeReportStatusCodeLib.inf + UefiDecompressLib|IntelFrameworkModulePkg/Library/BaseUefiTianoCustomDecompressLib/BaseUefiTianoCustomDecompressLib.inf + ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf + PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf + MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf + +[LibraryClasses.common.DXE_RUNTIME_DRIVER] + HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf + MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf + ReportStatusCodeLib|IntelFrameworkModulePkg/Library/DxeReportStatusCodeLibFramework/DxeReportStatusCodeLib.inf + CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf + +[LibraryClasses.ARM, LibraryClasses.AARCH64] + # + # It is not possible to prevent the ARM compiler for generic intrinsic functions. + # This library provides the instrinsic functions generate by a given compiler. + # [LibraryClasses.ARM] and NULL mean link this library into all ARM images. + # + NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf + + # Add support for GCC stack protector + NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf + +################################################################################ +# +# Pcd Section - list of all EDK II PCD Entries defined by this Platform +# +################################################################################ + +[PcdsFeatureFlag.common] + gEfiMdePkgTokenSpaceGuid.PcdComponentNameDisable|TRUE + gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnosticsDisable|TRUE + gEfiMdePkgTokenSpaceGuid.PcdComponentName2Disable|TRUE + gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnostics2Disable|TRUE + + # + # Control what commands are supported from the UI + # Turn these on and off to add features or save size + # + gEmbeddedTokenSpaceGuid.PcdEmbeddedMacBoot|TRUE + gEmbeddedTokenSpaceGuid.PcdEmbeddedDirCmd|TRUE + gEmbeddedTokenSpaceGuid.PcdEmbeddedHobCmd|TRUE + gEmbeddedTokenSpaceGuid.PcdEmbeddedHwDebugCmd|TRUE + gEmbeddedTokenSpaceGuid.PcdEmbeddedPciDebugCmd|TRUE + gEmbeddedTokenSpaceGuid.PcdEmbeddedIoEnable|FALSE + gEmbeddedTokenSpaceGuid.PcdEmbeddedScriptCmd|FALSE + + gEmbeddedTokenSpaceGuid.PcdCacheEnable|TRUE + + # Use the Vector Table location in CpuDxe. + # We will not copy the Vector Table at PcdCpuVectorBaseAddress + gArmTokenSpaceGuid.PcdRelocateVectorTable|FALSE + + gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob|TRUE + + # If TRUE, Graphics Output Protocol will be installed on virtual + # handle created by ConsplitterDxe. It could be set FALSE to save size. + gEfiMdeModulePkgTokenSpaceGuid.PcdConOutGopSupport|TRUE + gEfiMdeModulePkgTokenSpaceGuid.PcdConOutUgaSupport|FALSE + + # USB support + gEfiMdeModulePkgTokenSpaceGuid.PcdTurnOffUsbLegacySupport|TRUE + +[PcdsFixedAtBuild.common] + gArmPlatformTokenSpaceGuid.PcdFirmwareVendor|"Marvell" + gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString|L"MARVELL_EFI" + gArmPlatformTokenSpaceGuid.PcdCoreCount|4 + + ## Use the serial console (ConIn & ConOut) and the Graphic driver (ConOut) + gArmPlatformTokenSpaceGuid.PcdDefaultConOutPaths|L"VenHw(D3987D4B-971A-435F-8CAF-4967EB627241)/Uart(115200,8,N,1)/VenPcAnsi()" + gArmPlatformTokenSpaceGuid.PcdDefaultConInPaths|L"VenHw(D3987D4B-971A-435F-8CAF-4967EB627241)/Uart(115200,8,N,1)/VenPcAnsi()" + + gEmbeddedTokenSpaceGuid.PcdEmbeddedPrompt|"Marvell>> " + gEfiMdePkgTokenSpaceGuid.PcdMaximumUnicodeStringLength|1000000 + gEfiMdePkgTokenSpaceGuid.PcdMaximumAsciiStringLength|1000000 + gEfiMdePkgTokenSpaceGuid.PcdMaximumLinkedListLength|1000000 + gEfiMdePkgTokenSpaceGuid.PcdSpinLockTimeout|10000000 + gEfiMdePkgTokenSpaceGuid.PcdDebugClearMemoryValue|0xAF + gEfiMdePkgTokenSpaceGuid.PcdPerformanceLibraryPropertyMask|1 + gEfiMdePkgTokenSpaceGuid.PcdPostCodePropertyMask|0 + gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|320 + gEfiMdePkgTokenSpaceGuid.PcdDefaultTerminalType|1 + gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|3 + + # Required for Intel BDS + gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE + gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdShellFile|{ 0x83, 0xA5, 0x04, 0x7C, 0x3E, 0x9E, 0x1C, 0x4F, 0xAD, 0x65, 0xE0, 0x52, 0x68, 0xD0, 0xB4, 0xD1 } + + # ARM Generic Interrupt Controller + gArmTokenSpaceGuid.PcdGicDistributorBase|0xF0210000 + gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0xF0220000 + + # ARM Architectural Timer Support + gArmTokenSpaceGuid.PcdArmArchTimerFreqInHz|25000000 + gEmbeddedTokenSpaceGuid.PcdMetronomeTickPeriod|1000 + + # ARM SBSA Watchdog + gArmTokenSpaceGuid.PcdGenericWatchdogControlBase|0xF0620000 + gArmTokenSpaceGuid.PcdGenericWatchdogRefreshBase|0xF0600000 + gArmTokenSpaceGuid.PcdGenericWatchdogEl2IntrNum|34 + + # Serial + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio|TRUE + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseHardwareFlowControl|FALSE + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|0xF0512000 + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialBaudRate|115200 + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialClockRate|200000000 + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterStride|4 + + # RamDisk + gOpenPlatformTokenSpaceGuid.PcdRamDiskMaxSize|64 + + # DEBUG_ASSERT_ENABLED 0x01 + # DEBUG_PRINT_ENABLED 0x02 + # DEBUG_CODE_ENABLED 0x04 + # CLEAR_MEMORY_ENABLED 0x08 + # ASSERT_BREAKPOINT_ENABLED 0x10 + # ASSERT_DEADLOOP_ENABLED 0x20 + + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2f + + # DEBUG_INIT 0x00000001 // Initialization + # DEBUG_WARN 0x00000002 // Warnings + # DEBUG_LOAD 0x00000004 // Load events + # DEBUG_FS 0x00000008 // EFI File system + # DEBUG_POOL 0x00000010 // Alloc & Free (pool) + # DEBUG_PAGE 0x00000020 // Alloc & Free (page) + # DEBUG_INFO 0x00000040 // Informational debug messages + # DEBUG_DISPATCH 0x00000080 // PEI/DXE/SMM Dispatchers + # DEBUG_VARIABLE 0x00000100 // Variable + # DEBUG_BM 0x00000400 // Boot Manager + # DEBUG_BLKIO 0x00001000 // BlkIo Driver + # DEBUG_NET 0x00004000 // SNP Driver + # DEBUG_UNDI 0x00010000 // UNDI Driver + # DEBUG_LOADFILE 0x00020000 // LoadFile + # DEBUG_EVENT 0x00080000 // Event messages + # DEBUG_GCD 0x00100000 // Global Coherency Database changes + # DEBUG_CACHE 0x00200000 // Memory range cachability changes + # DEBUG_VERBOSE 0x00400000 // Detailed debug messages that may + # // significantly impact boot performance + # DEBUG_ERROR 0x80000000 // Error + +!if $(TARGET) == RELEASE + gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000000 +!else + gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x8000000F +!endif + gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07 + + gEmbeddedTokenSpaceGuid.PcdEmbeddedAutomaticBootCommand|"" + gEmbeddedTokenSpaceGuid.PcdEmbeddedDefaultTextColor|0x07 + gEmbeddedTokenSpaceGuid.PcdEmbeddedMemVariableStoreSize|0x10000 + + # + # Optional feature to help prevent EFI memory map fragments + # Turned on and off via: PcdPrePiProduceMemoryTypeInformationHob + # Values are in EFI Pages (4K). DXE Core will make sure that + # at least this much of each type of memory can be allocated + # from a single memory range. This way you only end up with + # maximum of two fragements for each type in the memory map + # (the memory used, and the free memory that was prereserved + # but not used). + # + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory|0 + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIMemoryNVS|0 + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType|0 + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData|50 + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode|20 + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesCode|400 + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesData|20000 + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderCode|20 + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderData|0 + + # We want to use the Shell Libraries but don't want it to initialise + # automatically. We initialise the libraries when the command is called by the + # Shell. + gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE + + # ARM Pcds + gArmTokenSpaceGuid.PcdArmUncachedMemoryMask|0x0000000000000000 + gArmTokenSpaceGuid.PcdSystemMemoryBase|0 + gArmTokenSpaceGuid.PcdSystemMemorySize|0x40000000 + gArmTokenSpaceGuid.PcdArmScr|0x531 + +################################################################################ +# +# Components Section - list of all EDK II Modules needed by this Platform +# +################################################################################ +[Components.common] + + # PEI Phase modules + ArmPlatformPkg/PrePi/PeiMPCore.inf + + # DXE + MdeModulePkg/Core/Dxe/DxeMain.inf { + <LibraryClasses> + PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf + NULL|MdeModulePkg/Library/DxeCrc32GuidedSectionExtractLib/DxeCrc32GuidedSectionExtractLib.inf + } + + # Architectural Protocols DXE + ArmPkg/Drivers/CpuDxe/CpuDxe.inf + ArmPkg/Drivers/ArmGic/ArmGicDxe.inf + ArmPkg/Drivers/TimerDxe/TimerDxe.inf + ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.inf + + MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf + MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf + MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf + MdeModulePkg/Universal/Variable/EmuRuntimeDxe/EmuVariableRuntimeDxe.inf + + EmbeddedPkg/EmbeddedMonotonicCounter/EmbeddedMonotonicCounter.inf + EmbeddedPkg/ResetRuntimeDxe/ResetRuntimeDxe.inf + EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf + EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf + + # Console packages + MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf + MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf + MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf + MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf + MdeModulePkg/Universal/SerialDxe/SerialDxe.inf + + # Human interface: + MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf + + # FAT filesystem + GPT/MBR partitioning + OpenPlatformPkg/Drivers/Block/ramdisk/ramdisk.inf + MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf + MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf + MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf + + # Application + EmbeddedPkg/Ebl/Ebl.inf + + # Bds - Use Intel BDS + MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf + MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf + MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf + IntelFrameworkModulePkg/Universal/BdsDxe/BdsDxe.inf + + # UEFI application (Shell Embedded Boot Loader) + ShellPkg/Application/Shell/Shell.inf { + <LibraryClasses> + ShellCommandLib|ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.inf + NULL|ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.inf + NULL|ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1CommandsLib.inf + NULL|ShellPkg/Library/UefiShellLevel3CommandsLib/UefiShellLevel3CommandsLib.inf + NULL|ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.inf + NULL|ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.inf + NULL|ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1CommandsLib.inf + NULL|ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1CommandsLib.inf + NULL|ShellPkg/Library/UefiShellTftpCommandLib/UefiShellTftpCommandLib.inf + HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf + PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf + BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.inf + + <PcdsFixedAtBuild> + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0xFF + gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE + gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|8000 + } diff --git a/Platforms/Marvell/Armada/Armada70x0.dsc b/Platforms/Marvell/Armada/Armada70x0.dsc new file mode 100644 index 0000000..8c7751a --- /dev/null +++ b/Platforms/Marvell/Armada/Armada70x0.dsc @@ -0,0 +1,48 @@ +#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. +# +################################################################################ +# +# Defines Section - statements that will be processed to create a Makefile. +# +################################################################################ +[Defines] + PLATFORM_NAME = Armada70x0 + PLATFORM_GUID = f837e231-cfc7-4f56-9a0f-5b218d746ae3 + PLATFORM_VERSION = 0.1 + DSC_SPECIFICATION = 0x00010005 + OUTPUT_DIRECTORY = Build/$(PLATFORM_NAME) + SUPPORTED_ARCHITECTURES = AARCH64 + BUILD_TARGETS = DEBUG|RELEASE + SKUID_IDENTIFIER = DEFAULT + FLASH_DEFINITION = OpenPlatformPkg/Platforms/Marvell/Armada/Armada70x0.fdf + +!include Armada.dsc.inc diff --git a/Platforms/Marvell/Armada/Armada70x0.fdf b/Platforms/Marvell/Armada/Armada70x0.fdf new file mode 100644 index 0000000..f42bcdd --- /dev/null +++ b/Platforms/Marvell/Armada/Armada70x0.fdf @@ -0,0 +1,265 @@ +# +# Copyright (C) Marvell International Ltd. and its affiliates +# +# 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. +# + +################################################################################ +# +# FD Section +# The [FD] Section is made up of the definition statements and a +# description of what goes into the Flash Device Image. Each FD section +# defines one flash "device" image. A flash device image may be one of +# the following: Removable media bootable image (like a boot floppy +# image,) an Option ROM image (that would be "flashed" into an add-in +# card,) a System "Flash" image (that would be burned into a system's +# flash) or an Update ("Capsule") image that will be used to update and +# existing system flash. +# +################################################################################ + +[FD.Armada70x0_EFI] +BaseAddress = 0x00000000|gArmTokenSpaceGuid.PcdFdBaseAddress # The base address of the Firmware in NOR Flash. +Size = 0x00400000|gArmTokenSpaceGuid.PcdFdSize # The size in bytes of the FLASH Device +ErasePolarity = 1 + +# This one is tricky, it must be: BlockSize * NumBlocks = Size +BlockSize = 0x00001000 +NumBlocks = 0x400 + +################################################################################ +# +# Following are lists of FD Region layout which correspond to the locations of different +# images within the flash device. +# +# Regions must be defined in ascending order and may not overlap. +# +# A Layout Region start with a eight digit hex offset (leading "0x" required) followed by +# the pipe "|" character, followed by the size of the region, also in hex with the leading +# "0x" characters. Like: +# Offset|Size +# PcdOffsetCName|PcdSizeCName +# RegionType <FV, DATA, or FILE> +# +################################################################################ + +0x00000000|0x000E0000 +gArmTokenSpaceGuid.PcdFvBaseAddress|gArmTokenSpaceGuid.PcdFvSize +FV = FVMAIN_COMPACT + + +################################################################################ +# +# FV Section +# +# [FV] section is used to define what components or modules are placed within a flash +# device file. This section also defines order the components and modules are positioned +# within the image. The [FV] section consists of define statements, set statements and +# module statements. +# +################################################################################ + +# DXE phase firmware volume +[FV.FvMain] +BlockSize = 0x40 +NumBlocks = 0 # This FV gets compressed so make it just big enough +FvAlignment = 8 # FV alignment and FV attributes setting. +ERASE_POLARITY = 1 +MEMORY_MAPPED = TRUE +STICKY_WRITE = TRUE +LOCK_CAP = TRUE +LOCK_STATUS = TRUE +WRITE_DISABLED_CAP = TRUE +WRITE_ENABLED_CAP = TRUE +WRITE_STATUS = TRUE +WRITE_LOCK_CAP = TRUE +WRITE_LOCK_STATUS = TRUE +READ_DISABLED_CAP = TRUE +READ_ENABLED_CAP = TRUE +READ_STATUS = TRUE +READ_LOCK_CAP = TRUE +READ_LOCK_STATUS = TRUE +FvNameGuid = 5eda4200-2c5f-43cb-9da3-0baf74b1b30c + + INF MdeModulePkg/Core/Dxe/DxeMain.inf + + # PI DXE Drivers producing Architectural Protocols (EFI Services) + INF ArmPkg/Drivers/CpuDxe/CpuDxe.inf + INF ArmPkg/Drivers/ArmGic/ArmGicDxe.inf + INF ArmPkg/Drivers/TimerDxe/TimerDxe.inf + INF ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.inf + INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf + INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf + INF MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf + INF MdeModulePkg/Universal/Variable/EmuRuntimeDxe/EmuVariableRuntimeDxe.inf + INF EmbeddedPkg/EmbeddedMonotonicCounter/EmbeddedMonotonicCounter.inf + INF EmbeddedPkg/ResetRuntimeDxe/ResetRuntimeDxe.inf + INF EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf + INF EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf + + # Multiple Console IO support + INF MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf + INF MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf + INF MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf + INF MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf + INF MdeModulePkg/Universal/SerialDxe/SerialDxe.inf + + # Human interface + INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf + + # FAT filesystem + GPT/MBR partitioning + INF OpenPlatformPkg/Drivers/Block/ramdisk/ramdisk.inf + INF MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf + INF MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf + INF FatBinPkg/EnhancedFatDxe/Fat.inf + INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf + + # UEFI application (Shell Embedded Boot Loader) + INF EmbeddedPkg/Ebl/Ebl.inf + + # UEFI application (Shell Embedded Boot Loader) + INF ShellPkg/Application/Shell/Shell.inf + + # Bds + INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf + INF MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf + INF MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf + INF IntelFrameworkModulePkg/Universal/BdsDxe/BdsDxe.inf + + +# PEI phase firmware volume +[FV.FVMAIN_COMPACT] +FvAlignment = 8 +FvForceRebase = TRUE +ERASE_POLARITY = 1 +MEMORY_MAPPED = TRUE +STICKY_WRITE = TRUE +LOCK_CAP = TRUE +LOCK_STATUS = TRUE +WRITE_DISABLED_CAP = TRUE +WRITE_ENABLED_CAP = TRUE +WRITE_STATUS = TRUE +WRITE_LOCK_CAP = TRUE +WRITE_LOCK_STATUS = TRUE +READ_DISABLED_CAP = TRUE +READ_ENABLED_CAP = TRUE +READ_STATUS = TRUE +READ_LOCK_CAP = TRUE +READ_LOCK_STATUS = TRUE + + INF ArmPlatformPkg/PrePi/PeiMPCore.inf + + FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 { + SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE { + SECTION FV_IMAGE = FVMAIN + } + } + +################################################################################ +# +# Rules are use with the [FV] section's module INF type to define +# how an FFS file is created for a given INF file. The following Rule are the default +# rules for the different module type. User can add the customized rules to define the +# content of the FFS file. +# +################################################################################ + + +############################################################################ +# Example of a DXE_DRIVER FFS file with a Checksum encapsulation section # +############################################################################ +# +#[Rule.Common.DXE_DRIVER] +# FILE DRIVER = $(NAMED_GUID) { +# DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex +# COMPRESS PI_STD { +# GUIDED { +# PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi +# UI STRING="$(MODULE_NAME)" Optional +# VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) +# } +# } +# } +# +############################################################################ + +[Rule.ARM.SEC] + FILE SEC = $(NAMED_GUID) RELOCS_STRIPPED { + TE TE Align = 32 $(INF_OUTPUT)/$(MODULE_NAME).efi + } + +# The AArch64 Vector Table requires a 2K alignment that is not supported by the FDF specification. +# It is the reason 4K is used instead of 2K for the module alignment. +[Rule.AARCH64.SEC] + FILE SEC = $(NAMED_GUID) RELOCS_STRIPPED { + TE TE Align = 4K $(INF_OUTPUT)/$(MODULE_NAME).efi + } + +[Rule.Common.PEI_CORE] + FILE PEI_CORE = $(NAMED_GUID) { + TE TE $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING ="$(MODULE_NAME)" Optional + } + +[Rule.Common.PEIM] + FILE PEIM = $(NAMED_GUID) { + PEI_DEPEX PEI_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex + TE TE $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + } + +[Rule.Common.PEIM.TIANOCOMPRESSED] + FILE PEIM = $(NAMED_GUID) DEBUG_MYTOOLS_IA32 { + PEI_DEPEX PEI_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex + GUIDED A31280AD-481E-41B6-95E8-127F4C984779 PROCESSING_REQUIRED = TRUE { + PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + } + } + +[Rule.Common.DXE_CORE] + FILE DXE_CORE = $(NAMED_GUID) { + PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + } + +[Rule.Common.UEFI_DRIVER] + FILE DRIVER = $(NAMED_GUID) { + DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex + PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + } + +[Rule.Common.UEFI_DRIVER.BINARY] + FILE DRIVER = $(NAMED_GUID) { + DXE_DEPEX DXE_DEPEX Optional |.depex + PE32 PE32 |.efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + } + +[Rule.Common.DXE_DRIVER] + FILE DRIVER = $(NAMED_GUID) { + DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex + PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + } + +[Rule.Common.DXE_RUNTIME_DRIVER] + FILE DRIVER = $(NAMED_GUID) { + DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex + PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + } + +[Rule.Common.UEFI_APPLICATION] + FILE APPLICATION = $(NAMED_GUID) { + UI STRING ="$(MODULE_NAME)" Optional + PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi + }
From: Jan Dąbroś jsd@semihalf.com
- Create Mpp Library, which allows to set MPP on board. - Create Platforms/Marvell/Marvell.dec file, which holds PCDs' declaration. - Export configuration capabilities via PCDs. - Prepare porting guide document
Because GetMppPcd has to be adjusted to possible 8 MPP registers, although unused, additional PcdChip<X>MppSel are added in order to satisfy preprocessor demands. For the same reason there are MPP PCDs for all of 4 possible chips.
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 --- Documentation/Marvell/PortingGuide/Mpp.txt | 48 ++++++++ Platforms/Marvell/Include/Library/MppLib.h | 42 +++++++ Platforms/Marvell/Library/MppLib/MppLib.c | 163 ++++++++++++++++++++++++++++ Platforms/Marvell/Library/MppLib/MppLib.inf | 107 ++++++++++++++++++ Platforms/Marvell/Marvell.dec | 106 ++++++++++++++++++ 5 files changed, 466 insertions(+) create mode 100644 Documentation/Marvell/PortingGuide/Mpp.txt create mode 100644 Platforms/Marvell/Include/Library/MppLib.h create mode 100644 Platforms/Marvell/Library/MppLib/MppLib.c create mode 100644 Platforms/Marvell/Library/MppLib/MppLib.inf create mode 100644 Platforms/Marvell/Marvell.dec
diff --git a/Documentation/Marvell/PortingGuide/Mpp.txt b/Documentation/Marvell/PortingGuide/Mpp.txt new file mode 100644 index 0000000..3e36b5f --- /dev/null +++ b/Documentation/Marvell/PortingGuide/Mpp.txt @@ -0,0 +1,48 @@ +MPP configuration +----------------- +Multi-Purpose Ports (MPP) are configurable through platform PCDs. +In order to set desired pin multiplexing, .dsc file needs to be modified. +(OpenPlatformPkg/Platforms/Marvell/Armada/{platform_name}.dsc - please refer to +Documentation/Build.txt for currently supported {platftorm_name} ) +Following PCDs are available: + + gMarvellTokenSpaceGuid.PcdMppChipCount + +Indicates how many different chips are placed on board. So far up to 4 chips +are supported. + +Every MPP PCD has <Num> part where + <Num> stands for chip ID (order is not important, but configuration will be + set for first PcdMppChipCount chips). + +Below is example for the first chip (Chip0). + + gMarvellTokenSpaceGuid.PcdChip0MppReverseFlag + +Indicates that register order is reversed. (Needs to be used only for AP806-Z1) + + gMarvellTokenSpaceGuid.PcdChip0MppBaseAddress + +This is base address for MPP configuration register. + + gMarvellTokenSpaceGuid.PcdChip0MppPinCount + +Defines how many MPP pins are available. + + gMarvellTokenSpaceGuid.PcdChip0MppSel0 + gMarvellTokenSpaceGuid.PcdChip0MppSel1 + gMarvellTokenSpaceGuid.PcdChip0MppSel2 + +This registers defines functions of 10 pins in ascending order. + +Examples +-------- +#APN806-A0 MPP SET + gMarvellTokenSpaceGuid.PcdChip0MppReverseFlag|FALSE + gMarvellTokenSpaceGuid.PcdChip0MppBaseAddress|0xF06F4000 + gMarvellTokenSpaceGuid.PcdChip0MppRegCount|3 + gMarvellTokenSpaceGuid.PcdChip0MppSel0|{ 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x0 } + gMarvellTokenSpaceGuid.PcdChip0MppSel1|{ 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } + +Set pin 6 and 7 to 0xa function: + gMarvellTokenSpaceGuid.PcdChip0MppSel0|{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0xa, 0x0, 0x0 } diff --git a/Platforms/Marvell/Include/Library/MppLib.h b/Platforms/Marvell/Include/Library/MppLib.h new file mode 100644 index 0000000..77c6cdb --- /dev/null +++ b/Platforms/Marvell/Include/Library/MppLib.h @@ -0,0 +1,42 @@ +/******************************************************************************** +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. + +*******************************************************************************/ + +#ifndef __MPPLIB_H__ +#define __MPPLIB_H__ + +EFI_STATUS +MppInitialize ( + ); + +#endif diff --git a/Platforms/Marvell/Library/MppLib/MppLib.c b/Platforms/Marvell/Library/MppLib/MppLib.c new file mode 100644 index 0000000..b24743c --- /dev/null +++ b/Platforms/Marvell/Library/MppLib/MppLib.c @@ -0,0 +1,163 @@ +/******************************************************************************** +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 <Library/ArmLib.h> +#include <Library/ArmPlatformLib.h> +#include <Library/DebugLib.h> +#include <Library/PcdLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/IoLib.h> + +#define MPP_PIN_VAL(pin,func) (((func) & 0xf) << ((pin) * 4)) +#define MPP_MAX_REGS 8 +#define MPP_PINS_PER_REG 8 +#define PCD_PINS_PER_GROUP 10 + +#define MAX_CHIPS 4 + +#define GET_PCD_PTR(id,num) PcdGetPtr(PcdChip##id##MppSel##num) +#define GET_PIN_COUNT(id) PcdGet32(PcdChip##id##MppPinCount) +#define GET_BASE(id) PcdGet64(PcdChip##id##MppBaseAddress) +#define GET_REV_FLAG(id) PcdGetBool(PcdChip##id##MppReverseFlag) + +/* We get chip number */ +#define GetMppPcd(id) { \ + PinCount[id] = GET_PIN_COUNT(id); \ + MppRegPcd[id][7] = GET_PCD_PTR(id,7); \ + MppRegPcd[id][6] = GET_PCD_PTR(id,6); \ + MppRegPcd[id][5] = GET_PCD_PTR(id,5); \ + MppRegPcd[id][4] = GET_PCD_PTR(id,4); \ + MppRegPcd[id][3] = GET_PCD_PTR(id,3); \ + MppRegPcd[id][2] = GET_PCD_PTR(id,2); \ + MppRegPcd[id][1] = GET_PCD_PTR(id,1); \ + MppRegPcd[id][0] = GET_PCD_PTR(id,0); \ + BaseAddr[id] = GET_BASE(id); \ + ReverseFlag[id] = GET_REV_FLAG(id); \ +} + +STATIC +VOID +SetRegisterValue ( + UINT8 RegCount, + UINT8 **MppRegPcd, + UINTN BaseAddr, + BOOLEAN ReverseFlag + ) +{ + UINT32 i, j, CtrlVal; + INTN Sign; + + Sign = ReverseFlag ? -1 : 1; + + for (i = 0; i < RegCount; i++) { + CtrlVal = 0; + for (j = 0; j < MPP_PINS_PER_REG; j++) { + CtrlVal |= MPP_PIN_VAL(7 * (UINTN) ReverseFlag + j * Sign, + MppRegPcd[i][7 * (UINTN) ReverseFlag + j * Sign]); + } + MmioWrite32 (BaseAddr + 4 * i * Sign, CtrlVal); + } +} + +STATIC +/* Transform PCD MPP group format into hardware register format */ +UINT8 +PcdToMppRegs ( + UINTN PinCount, + UINT8 **MppRegPcd + ) +{ + UINT8 MppRegPcdTmp[MPP_MAX_REGS][MPP_PINS_PER_REG]; + UINT8 PcdGroupCount, MppRegCount; + UINTN i, j, k, l; + + if (PinCount == 0) { + return 0; + } + + PcdGroupCount = PinCount / PCD_PINS_PER_GROUP; + if ((PinCount % PCD_PINS_PER_GROUP) != 0) { + PcdGroupCount += 1; + } + + MppRegCount = PinCount / MPP_PINS_PER_REG; + if ((PinCount % MPP_PINS_PER_REG) != 0) { + MppRegCount += 1; + } + + /* Fill temporary table with data from PCD groups in HW format */ + for (i = 0; i < PcdGroupCount; i++) { + for (j = 0; j < PCD_PINS_PER_GROUP; j++) { + k = (PCD_PINS_PER_GROUP * i + j) / MPP_PINS_PER_REG; + l = (PCD_PINS_PER_GROUP * i + j) % MPP_PINS_PER_REG; + MppRegPcdTmp[k][l] = MppRegPcd[i][j]; + } + } + + /* Update input table */ + for (i = 0; i < MppRegCount; i++) { + for (j = 0; j < MPP_PINS_PER_REG; j++) { + MppRegPcd[i][j] = MppRegPcdTmp[i][j]; + } + } + + return MppRegCount; +} + +EFI_STATUS +MppInitialize ( + ) +{ + UINTN BaseAddr[MAX_CHIPS], PinCount[MAX_CHIPS], RegCount; + BOOLEAN ReverseFlag[MAX_CHIPS]; + UINT8 *MppRegPcd[MAX_CHIPS][MPP_MAX_REGS]; + UINT32 i, ChipCount; + + ChipCount = PcdGet32 (PcdMppChipCount); + + /* Read all needed PCD for MPP configuration */ + GetMppPcd(0); + GetMppPcd(1); + GetMppPcd(2); + GetMppPcd(3); + + for (i = 0; i < MAX_CHIPS; i++) { + if (i == ChipCount) + break; + RegCount = PcdToMppRegs (PinCount[i], MppRegPcd[i]); + SetRegisterValue (RegCount, MppRegPcd[i], BaseAddr[i], ReverseFlag[i]); + } + + return EFI_SUCCESS; +} diff --git a/Platforms/Marvell/Library/MppLib/MppLib.inf b/Platforms/Marvell/Library/MppLib/MppLib.inf new file mode 100644 index 0000000..510064f --- /dev/null +++ b/Platforms/Marvell/Library/MppLib/MppLib.inf @@ -0,0 +1,107 @@ +# +# 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 = 0x00010005 + BASE_NAME = MarvellMppLib + FILE_GUID = 3f19b642-4a49-4dfd-8f4a-205dd38432bb + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = MppLib + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + ArmPkg/ArmPkg.dec + ArmPlatformPkg/ArmPlatformPkg.dec + OpenPlatformPkg/Platforms/Marvell/Marvell.dec + +[LibraryClasses] + ArmLib + DebugLib + MemoryAllocationLib + PcdLib + IoLib + +[Sources.common] + MppLib.c + +[FixedPcd] + gMarvellTokenSpaceGuid.PcdMppChipCount + + gMarvellTokenSpaceGuid.PcdChip0MppReverseFlag + gMarvellTokenSpaceGuid.PcdChip0MppBaseAddress + gMarvellTokenSpaceGuid.PcdChip0MppPinCount + gMarvellTokenSpaceGuid.PcdChip0MppSel0 + gMarvellTokenSpaceGuid.PcdChip0MppSel1 + gMarvellTokenSpaceGuid.PcdChip0MppSel2 + gMarvellTokenSpaceGuid.PcdChip0MppSel3 + gMarvellTokenSpaceGuid.PcdChip0MppSel4 + gMarvellTokenSpaceGuid.PcdChip0MppSel5 + gMarvellTokenSpaceGuid.PcdChip0MppSel6 + gMarvellTokenSpaceGuid.PcdChip0MppSel7 + + gMarvellTokenSpaceGuid.PcdChip1MppReverseFlag + gMarvellTokenSpaceGuid.PcdChip1MppBaseAddress + gMarvellTokenSpaceGuid.PcdChip1MppPinCount + gMarvellTokenSpaceGuid.PcdChip1MppSel0 + gMarvellTokenSpaceGuid.PcdChip1MppSel1 + gMarvellTokenSpaceGuid.PcdChip1MppSel2 + gMarvellTokenSpaceGuid.PcdChip1MppSel3 + gMarvellTokenSpaceGuid.PcdChip1MppSel4 + gMarvellTokenSpaceGuid.PcdChip1MppSel5 + gMarvellTokenSpaceGuid.PcdChip1MppSel6 + gMarvellTokenSpaceGuid.PcdChip1MppSel7 + + gMarvellTokenSpaceGuid.PcdChip2MppReverseFlag + gMarvellTokenSpaceGuid.PcdChip2MppBaseAddress + gMarvellTokenSpaceGuid.PcdChip2MppPinCount + gMarvellTokenSpaceGuid.PcdChip2MppSel0 + gMarvellTokenSpaceGuid.PcdChip2MppSel1 + gMarvellTokenSpaceGuid.PcdChip2MppSel2 + gMarvellTokenSpaceGuid.PcdChip2MppSel3 + gMarvellTokenSpaceGuid.PcdChip2MppSel4 + gMarvellTokenSpaceGuid.PcdChip2MppSel5 + gMarvellTokenSpaceGuid.PcdChip2MppSel6 + gMarvellTokenSpaceGuid.PcdChip2MppSel7 + + gMarvellTokenSpaceGuid.PcdChip3MppReverseFlag + gMarvellTokenSpaceGuid.PcdChip3MppBaseAddress + gMarvellTokenSpaceGuid.PcdChip3MppPinCount + gMarvellTokenSpaceGuid.PcdChip3MppSel0 + gMarvellTokenSpaceGuid.PcdChip3MppSel1 + gMarvellTokenSpaceGuid.PcdChip3MppSel2 + gMarvellTokenSpaceGuid.PcdChip3MppSel3 + gMarvellTokenSpaceGuid.PcdChip3MppSel4 + gMarvellTokenSpaceGuid.PcdChip3MppSel5 + gMarvellTokenSpaceGuid.PcdChip3MppSel6 + gMarvellTokenSpaceGuid.PcdChip3MppSel7 + diff --git a/Platforms/Marvell/Marvell.dec b/Platforms/Marvell/Marvell.dec new file mode 100644 index 0000000..fee8025 --- /dev/null +++ b/Platforms/Marvell/Marvell.dec @@ -0,0 +1,106 @@ +# 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. +# + +[Defines] + DEC_SPECIFICATION = 0x00010005 + PACKAGE_NAME = OpenPlatformMarvellPkg + PACKAGE_GUID = c372916e-83ad-4b2a-8410-bbc31bd9e68f + PACKAGE_VERSION = 0.1 + +################################################################################ +# +# Include Section - list of Include Paths that are provided by this package. +# Comments are used for Keywords and Module Types. +# +# Supported Module Types: +# BASE SEC PEI_CORE PEIM DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER DXE_SAL_DRIVER UEFI_DRIVER UEFI_APPLICATION +# +################################################################################ + +[Includes] + Include + +[Guids.common] + gMarvellTokenSpaceGuid = { 0xf995c6c8, 0xbc9b, 0x4e93, { 0xbd, 0xcf, 0x49, 0x90, 0xc6, 0xe7, 0x8c, 0x7f } } + +[PcdsFixedAtBuild.common] +#MPP + gMarvellTokenSpaceGuid.PcdMppChipCount|0|UINT32|0x30000001 + + gMarvellTokenSpaceGuid.PcdChip0MppReverseFlag|FALSE|BOOLEAN|0x30000002 + gMarvellTokenSpaceGuid.PcdChip0MppBaseAddress|0|UINT64|0x30000003 + gMarvellTokenSpaceGuid.PcdChip0MppPinCount|0|UINT32|0x30000004 + gMarvellTokenSpaceGuid.PcdChip0MppSel0|{ 0 }|VOID*|0x30000005 + gMarvellTokenSpaceGuid.PcdChip0MppSel1|{ 0 }|VOID*|0x30000006 + gMarvellTokenSpaceGuid.PcdChip0MppSel2|{ 0 }|VOID*|0x30000007 + gMarvellTokenSpaceGuid.PcdChip0MppSel3|{ 0 }|VOID*|0x30000008 + gMarvellTokenSpaceGuid.PcdChip0MppSel4|{ 0 }|VOID*|0x30000009 + gMarvellTokenSpaceGuid.PcdChip0MppSel5|{ 0 }|VOID*|0x30000010 + gMarvellTokenSpaceGuid.PcdChip0MppSel6|{ 0 }|VOID*|0x30000011 + gMarvellTokenSpaceGuid.PcdChip0MppSel7|{ 0 }|VOID*|0x30000012 + + gMarvellTokenSpaceGuid.PcdChip1MppReverseFlag|FALSE|BOOLEAN|0x30000013 + gMarvellTokenSpaceGuid.PcdChip1MppBaseAddress|0|UINT64|0x30000014 + gMarvellTokenSpaceGuid.PcdChip1MppPinCount|0|UINT32|0x30000015 + gMarvellTokenSpaceGuid.PcdChip1MppSel0|{ 0 }|VOID*|0x30000016 + gMarvellTokenSpaceGuid.PcdChip1MppSel1|{ 0 }|VOID*|0x30000017 + gMarvellTokenSpaceGuid.PcdChip1MppSel2|{ 0 }|VOID*|0x30000018 + gMarvellTokenSpaceGuid.PcdChip1MppSel3|{ 0 }|VOID*|0x30000019 + gMarvellTokenSpaceGuid.PcdChip1MppSel4|{ 0 }|VOID*|0x30000020 + gMarvellTokenSpaceGuid.PcdChip1MppSel5|{ 0 }|VOID*|0x30000021 + gMarvellTokenSpaceGuid.PcdChip1MppSel6|{ 0 }|VOID*|0x30000022 + gMarvellTokenSpaceGuid.PcdChip1MppSel7|{ 0 }|VOID*|0x30000023 + + gMarvellTokenSpaceGuid.PcdChip2MppReverseFlag|FALSE|BOOLEAN|0x30000024 + gMarvellTokenSpaceGuid.PcdChip2MppBaseAddress|0|UINT64|0x30000025 + gMarvellTokenSpaceGuid.PcdChip2MppPinCount|0|UINT32|0x30000026 + gMarvellTokenSpaceGuid.PcdChip2MppSel0|{ 0 }|VOID*|0x30000027 + gMarvellTokenSpaceGuid.PcdChip2MppSel1|{ 0 }|VOID*|0x30000028 + gMarvellTokenSpaceGuid.PcdChip2MppSel2|{ 0 }|VOID*|0x30000029 + gMarvellTokenSpaceGuid.PcdChip2MppSel3|{ 0 }|VOID*|0x30000030 + gMarvellTokenSpaceGuid.PcdChip2MppSel4|{ 0 }|VOID*|0x30000031 + gMarvellTokenSpaceGuid.PcdChip2MppSel5|{ 0 }|VOID*|0x30000032 + gMarvellTokenSpaceGuid.PcdChip2MppSel6|{ 0 }|VOID*|0x30000033 + gMarvellTokenSpaceGuid.PcdChip2MppSel7|{ 0 }|VOID*|0x30000034 + + gMarvellTokenSpaceGuid.PcdChip3MppReverseFlag|FALSE|BOOLEAN|0x30000035 + gMarvellTokenSpaceGuid.PcdChip3MppBaseAddress|0|UINT64|0x30000036 + gMarvellTokenSpaceGuid.PcdChip3MppPinCount|0|UINT32|0x30000037 + gMarvellTokenSpaceGuid.PcdChip3MppSel0|{ 0 }|VOID*|0x30000038 + gMarvellTokenSpaceGuid.PcdChip3MppSel1|{ 0 }|VOID*|0x30000039 + gMarvellTokenSpaceGuid.PcdChip3MppSel2|{ 0 }|VOID*|0x30000040 + gMarvellTokenSpaceGuid.PcdChip3MppSel3|{ 0 }|VOID*|0x30000041 + gMarvellTokenSpaceGuid.PcdChip3MppSel4|{ 0 }|VOID*|0x30000042 + gMarvellTokenSpaceGuid.PcdChip3MppSel5|{ 0 }|VOID*|0x30000043 + gMarvellTokenSpaceGuid.PcdChip3MppSel6|{ 0 }|VOID*|0x30000044 + gMarvellTokenSpaceGuid.PcdChip3MppSel7|{ 0 }|VOID*|0x30000045 +
From: Jan Dąbroś jsd@semihalf.com
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 --- Platforms/Marvell/Armada/Armada.dsc.inc | 1 + Platforms/Marvell/Armada/Armada70x0.dsc | 28 ++++++++++++++++++++++ .../Armada/Library/Armada70x0Lib/Armada70x0Lib.c | 2 ++ .../Armada/Library/Armada70x0Lib/Armada70x0Lib.inf | 2 ++ 4 files changed, 33 insertions(+)
diff --git a/Platforms/Marvell/Armada/Armada.dsc.inc b/Platforms/Marvell/Armada/Armada.dsc.inc index 530b867..80a2c8c 100644 --- a/Platforms/Marvell/Armada/Armada.dsc.inc +++ b/Platforms/Marvell/Armada/Armada.dsc.inc @@ -31,6 +31,7 @@ # [LibraryClasses.common] ArmPlatformLib|OpenPlatformPkg/Platforms/Marvell/Armada/Library/Armada70x0Lib/Armada70x0Lib.inf + MppLib|OpenPlatformPkg/Platforms/Marvell/Library/MppLib/MppLib.inf
DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf UncachedMemoryAllocationLib|ArmPkg/Library/UncachedMemoryAllocationLib/UncachedMemoryAllocationLib.inf diff --git a/Platforms/Marvell/Armada/Armada70x0.dsc b/Platforms/Marvell/Armada/Armada70x0.dsc index 8c7751a..9bd66e0 100644 --- a/Platforms/Marvell/Armada/Armada70x0.dsc +++ b/Platforms/Marvell/Armada/Armada70x0.dsc @@ -46,3 +46,31 @@ FLASH_DEFINITION = OpenPlatformPkg/Platforms/Marvell/Armada/Armada70x0.fdf
!include Armada.dsc.inc + +################################################################################ +# +# Pcd Section - list of all EDK II PCD Entries defined by this Platform +# +################################################################################ +[PcdsFixedAtBuild.common] + #MPP + gMarvellTokenSpaceGuid.PcdMppChipCount|2 + + # APN806-A0 MPP SET + gMarvellTokenSpaceGuid.PcdChip0MppReverseFlag|FALSE + gMarvellTokenSpaceGuid.PcdChip0MppBaseAddress|0xF06F4000 + gMarvellTokenSpaceGuid.PcdChip0MppPinCount|20 + gMarvellTokenSpaceGuid.PcdChip0MppSel0|{ 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 } + gMarvellTokenSpaceGuid.PcdChip0MppSel1|{ 0x1, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3 } + + # CP110 MPP SET - Router configuration + gMarvellTokenSpaceGuid.PcdChip1MppReverseFlag|FALSE + gMarvellTokenSpaceGuid.PcdChip1MppBaseAddress|0xF2440000 + gMarvellTokenSpaceGuid.PcdChip1MppPinCount|64 + gMarvellTokenSpaceGuid.PcdChip1MppSel0|{ 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4 } + gMarvellTokenSpaceGuid.PcdChip1MppSel1|{ 0x4, 0x4, 0x0, 0x3, 0x3, 0x3, 0x3, 0x0, 0x0, 0x0 } + gMarvellTokenSpaceGuid.PcdChip1MppSel2|{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, 0xA } + gMarvellTokenSpaceGuid.PcdChip1MppSel3|{ 0xA, 0x0, 0x7, 0x0, 0x7, 0x7, 0x7, 0x2, 0x2, 0x0 } + gMarvellTokenSpaceGuid.PcdChip1MppSel4|{ 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 } + gMarvellTokenSpaceGuid.PcdChip1MppSel5|{ 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0xE, 0xE, 0xE, 0xE } + gMarvellTokenSpaceGuid.PcdChip1MppSel6|{ 0xE, 0xE, 0xE, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } diff --git a/Platforms/Marvell/Armada/Library/Armada70x0Lib/Armada70x0Lib.c b/Platforms/Marvell/Armada/Library/Armada70x0Lib/Armada70x0Lib.c index 8609700..a2b25e1 100644 --- a/Platforms/Marvell/Armada/Library/Armada70x0Lib/Armada70x0Lib.c +++ b/Platforms/Marvell/Armada/Library/Armada70x0Lib/Armada70x0Lib.c @@ -15,6 +15,7 @@
#include <Library/ArmLib.h> #include <Library/ArmPlatformLib.h> +#include <Library/MppLib.h> #include <Ppi/ArmMpCoreInfo.h>
@@ -93,6 +94,7 @@ ArmPlatformInitialize (
//TODO: Add basic platfrom initialization
+ MppInitialize (); return RETURN_SUCCESS; }
diff --git a/Platforms/Marvell/Armada/Library/Armada70x0Lib/Armada70x0Lib.inf b/Platforms/Marvell/Armada/Library/Armada70x0Lib/Armada70x0Lib.inf index 2e2120e..bd78406 100644 --- a/Platforms/Marvell/Armada/Library/Armada70x0Lib/Armada70x0Lib.inf +++ b/Platforms/Marvell/Armada/Library/Armada70x0Lib/Armada70x0Lib.inf @@ -43,11 +43,13 @@ MdeModulePkg/MdeModulePkg.dec ArmPkg/ArmPkg.dec ArmPlatformPkg/ArmPlatformPkg.dec + OpenPlatformPkg/Platforms/Marvell/Marvell.dec
[LibraryClasses] ArmLib DebugLib MemoryAllocationLib + MppLib
[Sources.common] Armada70x0Lib.c
From: Jan Dąbroś jsd@semihalf.com
Since PCD tables are byte arrays, it is impossible to provide big values (e.g. memory addresses) for multiple devices in simple PCD entry. In order to overcome this, strings may be used. ParsePcdLib allows parsing PCD string entry.
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 --- Platforms/Marvell/Include/Library/ParsePcdLib.h | 46 +++++ .../Marvell/Library/ParsePcdLib/ParsePcdLib.c | 228 +++++++++++++++++++++ .../Marvell/Library/ParsePcdLib/ParsePcdLib.inf | 50 +++++ 3 files changed, 324 insertions(+) create mode 100644 Platforms/Marvell/Include/Library/ParsePcdLib.h create mode 100644 Platforms/Marvell/Library/ParsePcdLib/ParsePcdLib.c create mode 100644 Platforms/Marvell/Library/ParsePcdLib/ParsePcdLib.inf
diff --git a/Platforms/Marvell/Include/Library/ParsePcdLib.h b/Platforms/Marvell/Include/Library/ParsePcdLib.h new file mode 100644 index 0000000..a255685 --- /dev/null +++ b/Platforms/Marvell/Include/Library/ParsePcdLib.h @@ -0,0 +1,46 @@ +/******************************************************************************** +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. + +*******************************************************************************/ + +#ifndef __PARSEPCDLIB_H__ +#define __PARSEPCDLIB_H__ + +EFI_STATUS +ParsePcdString ( + IN CHAR16 *PcdString, + IN UINT8 Count, + OUT UINTN *ValueTable, + OUT CHAR16 **StrTable + ); + +#endif diff --git a/Platforms/Marvell/Library/ParsePcdLib/ParsePcdLib.c b/Platforms/Marvell/Library/ParsePcdLib/ParsePcdLib.c new file mode 100644 index 0000000..9a4be8e --- /dev/null +++ b/Platforms/Marvell/Library/ParsePcdLib/ParsePcdLib.c @@ -0,0 +1,228 @@ +/******************************************************************************** +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. + +*******************************************************************************/ +#define CHAR_NULL 0x0000 + +#include <Library/BaseLib.h> +#include <Uefi.h> +#include <Library/UefiLib.h> +#include <Library/DebugLib.h> + +STATIC +CHAR16 +CharToUpper ( + IN CHAR16 Char + ) +{ + + if (Char >= L'a' && Char <= L'z') { + return (CHAR16) (Char - (L'a' - L'A')); + } + + return Char; +} + +STATIC +BOOLEAN +IsDecimalDigitChar ( + IN CHAR16 Char + ) +{ + + return (BOOLEAN) (Char >= L'0' && Char <= L'9'); +} + + +STATIC +UINTN +HexCharToUintn ( + IN CHAR16 Char + ) +{ + if (IsDecimalDigitChar (Char)) { + return Char - L'0'; + } + + return (UINTN) (10 + CharToUpper (Char) - L'A'); +} + +STATIC +BOOLEAN +IsHexDigitCharacter ( + CHAR16 Char + ) +{ + + return (BOOLEAN) ((Char >= L'0' && Char <= L'9') || (Char >= L'A' && + Char <= L'F') || (Char >= L'a' && Char <= L'f')); +} + +STATIC +UINTN +HexStrToUintn ( + CHAR16 *String + ) +{ + UINTN Result = 0; + + if (String == NULL || StrSize(String) == 0) { + return (UINTN)(-1); + } + + // Ignore spaces and tabs + while ((*String == L' ') || (*String == L'\t')) { + String++; + } + + // Ignore leading zeros after spaces + while (*String == L'0') { + String++; + } + + if (CharToUpper (*String) != L'X') { + return (UINTN)(-1); + } + + // Skip 'x' + String++; + + while (IsHexDigitCharacter (*String)) { + Result <<= 4; + Result += HexCharToUintn (*String); + String++; + } + + return (UINTN) Result; +} + +STATIC +UINTN +DecimalStrToUintn ( + CHAR16 *String + ) +{ + UINTN Result = 0; + + while (IsDecimalDigitChar (*String)) { + Result = 10 * Result + (*String - L'0'); + String++; + } + + return Result; +} + +STATIC +UINTN +StrToUintn ( + CHAR16 *String + ) +{ + CHAR16 *Walker; + + // Chop off leading spaces + for (Walker = String; Walker != NULL && *Walker != CHAR_NULL && *Walker == L' '; Walker++); + + if (StrnCmp(Walker, L"0x", 2) == 0 || StrnCmp(Walker, L"0X", 2) == 0) { + return HexStrToUintn (Walker); + } else { + return DecimalStrToUintn (Walker); + } +} + +EFI_STATUS +ParsePcdString ( + IN CHAR16 *PcdString, + IN UINT8 Count, + OUT UINTN *ValueTable, + OUT CHAR16 **StrTable + ) +{ + BOOLEAN ValueFlag = FALSE; + CHAR16 *Walker; + UINTN i, Tmp = 0; + + if (ValueTable != NULL) { + ValueFlag = TRUE; + } + + // Set pointer at the end of PCD string + Walker = PcdString + StrLen (PcdString); + for (i = 0; i < Count; i++) { + while ((--Walker) >= PcdString) { + if (*Walker == L';') { + // Cut off parsed chunk from PCD string by replacing ';' with + // null-terminator + *Walker = '\0'; + if (ValueFlag) { + Tmp = StrToUintn ((Walker + 1)); + if ((UINTN)(-1) == Tmp) { + return EFI_INVALID_PARAMETER; + } + // Entry is parsed from the end to the beginning + // so fill table in the same manner + ValueTable[Count - (i + 1)] = Tmp; + } else { + StrTable[Count - (i + 1)] = Walker + 1; + } + Walker--; + break; + } + if (Walker == PcdString) { + if (ValueFlag) { + Tmp = StrToUintn ((Walker)); + if (Tmp == (UINTN)(-1)) { + return EFI_INVALID_PARAMETER; + } + } + // Last device's entry should be added to the table here. + // If not, return error + if (i != (Count - 1)) { + DEBUG((DEBUG_ERROR, "ParsePcdLib: Please set PCD value for every " + "device\n")); + return EFI_INVALID_PARAMETER; + } + // We parse from the end to the beginning + // so fill table in the same manner + if (ValueFlag) { + ValueTable[Count - (i + 1)] = Tmp; + } else { + StrTable[Count - (i + 1)] = Walker; + } + // End both loops + return EFI_SUCCESS; + } + } + } + + return EFI_SUCCESS; +} diff --git a/Platforms/Marvell/Library/ParsePcdLib/ParsePcdLib.inf b/Platforms/Marvell/Library/ParsePcdLib/ParsePcdLib.inf new file mode 100644 index 0000000..b4db621 --- /dev/null +++ b/Platforms/Marvell/Library/ParsePcdLib/ParsePcdLib.inf @@ -0,0 +1,50 @@ +# 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. +# + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = ParsePcdLib + FILE_GUID = 698d85a0-a952-453e-b8a4-1d6ea338a38e + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = ParsePcdLib + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + ArmLib + DebugLib + +[Sources.common] + ParsePcdLib.c
From: Jan Dąbroś jsd@semihalf.com
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 --- Platforms/Marvell/Armada/Armada.dsc.inc | 1 + 1 file changed, 1 insertion(+)
diff --git a/Platforms/Marvell/Armada/Armada.dsc.inc b/Platforms/Marvell/Armada/Armada.dsc.inc index 80a2c8c..52c60f6 100644 --- a/Platforms/Marvell/Armada/Armada.dsc.inc +++ b/Platforms/Marvell/Armada/Armada.dsc.inc @@ -32,6 +32,7 @@ [LibraryClasses.common] ArmPlatformLib|OpenPlatformPkg/Platforms/Marvell/Armada/Library/Armada70x0Lib/Armada70x0Lib.inf MppLib|OpenPlatformPkg/Platforms/Marvell/Library/MppLib/MppLib.inf + ParsePcdLib|OpenPlatformPkg/Platforms/Marvell/Library/ParsePcdLib/ParsePcdLib.inf
DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf UncachedMemoryAllocationLib|ArmPkg/Library/UncachedMemoryAllocationLib/UncachedMemoryAllocationLib.inf
From: Bartosz Szczepanek bsz@semihalf.com
MvI2cDxe driver was adapted to generic UEFI I2C stack. Connection with following interfaces was required: - EFI_I2C_MASTER_PROTOCOL - EFI_I2C_BUS_CONFIGURATION_MANAGEMENT_PROTOCOL - EFI_I2C_ENUMERATE_PROTOCOL
Driver exports configuration options via PCDs. Configurable options include: - PcdI2cSlaveAddresses - should contain a list of valid I2C devices' addresses on bus - PcdI2cBaseAddresses - physical address of I2C controller registers - PcdI2cClockFrequency - I2c clock frequency on platform
Drivers of devices on I2C bus should never use EFI_I2C_MASTER_PROTOCOL directly. Instead, these ought to utilise EFI_I2C_IO_PROTOCOL produced by generic UEFI stack.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Bartosz Szczepanek bsz@semihalf.com Signed-off-by: Marcin Wojtas mw@semihalf.com --- Documentation/Marvell/Drivers/I2cDriver.txt | 64 +++ Documentation/Marvell/PortingGuide/I2c.txt | 20 + Drivers/I2c/MvI2cDxe/MvI2cDxe.c | 739 ++++++++++++++++++++++++++++ Drivers/I2c/MvI2cDxe/MvI2cDxe.h | 269 ++++++++++ Drivers/I2c/MvI2cDxe/MvI2cDxe.inf | 75 +++ Platforms/Marvell/Marvell.dec | 8 + 6 files changed, 1175 insertions(+) create mode 100644 Documentation/Marvell/Drivers/I2cDriver.txt create mode 100644 Documentation/Marvell/PortingGuide/I2c.txt create mode 100755 Drivers/I2c/MvI2cDxe/MvI2cDxe.c create mode 100644 Drivers/I2c/MvI2cDxe/MvI2cDxe.h create mode 100755 Drivers/I2c/MvI2cDxe/MvI2cDxe.inf
diff --git a/Documentation/Marvell/Drivers/I2cDriver.txt b/Documentation/Marvell/Drivers/I2cDriver.txt new file mode 100644 index 0000000..2f890de --- /dev/null +++ b/Documentation/Marvell/Drivers/I2cDriver.txt @@ -0,0 +1,64 @@ +1. Introduction +--------------- +**MvI2cDxe** is a driver supporting I2C controller on Marvell SOCs boards. +It is connected through protocols to generic UEFI I2C stack, which exposes +IO functionality to drivers of specific devices on I2C bus. + +2. MvI2cDxe driver design +-------------------------- +MvI2cDxe produces several protocols from generic I2C stack: + - EFI_I2C_MASTER_PROTOCOL, + - EFI_I2C_ENUMERATE_PROTOCOL, + - EFI_I2C_BUS_CONFIGURATION_MANAGEMENT_PROTOCOL + - general-purpose EFI_DRIVER_BINDING_PROTOCOL. + + 2.1 EFI_I2C_MASTER_PROTOCOL + --------------------------- + This is the most important protocol produced by MvI2cDxe. Following functions + are implemented: + + /// + /// Reset the I2C host controller. + /// + EFI_I2C_MASTER_PROTOCOL_RESET Reset; + + /// + /// Start an I2C transaction in master mode on the host controller. + /// + EFI_I2C_MASTER_PROTOCOL_START_REQUEST StartRequest; + + StartRequest and Reset functions are used by I2cHost. + These should **not** be used by I2C device drivers - required + synchronization is not provided. Instead, members of EFI_I2C_IO_PROTOCOL + should be used. + + 2.2 EFI_I2C_BUS_CONFIGURATION_MANAGEMENT_PROTOCOL + ------------------------------------------------- + The only function exposed via this protocol is MvI2cEnableConf. It is + required by I2C stack in order to allow changing I2C bus configuration from + device drivers. + + 2.3 EFI_I2C_ENUMERATE_PROTOCOL + ------------------------------ + Provides Enumerate function, which is used by I2cBus code as an iterator over + devices on I2C bus. + + typedef + EFI_STATUS + (EFIAPI *EFI_I2C_ENUMERATE_PROTOCOL_ENUMERATE) ( + IN CONST EFI_I2C_ENUMERATE_PROTOCOL *This, + IN OUT CONST EFI_I2C_DEVICE **Device + ); + + /// + /// Traverse the set of I2C devices on an I2C bus. This routine + /// returns the next I2C device on an I2C bus. + /// + EFI_I2C_ENUMERATE_PROTOCOL_ENUMERATE Enumerate; + + MvI2cDevice creates EFI_I2C_DEVICE structure for every device on the bus. + Due to the fact that hardware-based I2C enumeration isn't safe, information + about attached devices should be provided through PCDs. After EFI_I2C_DEVICE + structure is created and filled properly, it is returned to I2cBus. It is + followed by attachment of I2C device driver. + diff --git a/Documentation/Marvell/PortingGuide/I2c.txt b/Documentation/Marvell/PortingGuide/I2c.txt new file mode 100644 index 0000000..28ae1ef --- /dev/null +++ b/Documentation/Marvell/PortingGuide/I2c.txt @@ -0,0 +1,20 @@ +1. Porting I2C driver to a new SOC +---------------------------------- +In order to enable driver on a new platform, following steps need to be taken: + - add following line to .dsc file: + OpenPlatformPkg/Drivers/I2c/MvI2cDxe/MvI2cDxe.inf + - add following line to .fdf file: + INF OpenPlatformPkg/Drivers/I2c/MvI2cDxe/MvI2cDxe.inf + - add PCDs with relevant values to .dsc file: + gMarvellTokenSpaceGuid.PcdI2cSlaveAddresses|{ 0x50, 0x57 } + (addresses of I2C slave devices on bus) + gMarvellTokenSpaceGuid.PcdI2cSlaveBuses|{ 0x0, 0x0 } + (buses to which accoring slaves are attached) + gMarvellTokenSpaceGuid.PcdI2cBusCount|2 + (number of SoC's I2C buses) + gMarvellTokenSpaceGuid.PcdI2cBaseAddresses|L"0xF2701000;0xF2701100" + (base addresses of I2C controller buses) + gMarvellTokenSpaceGuid.PcdI2cClockFrequency|200000000 + (I2C host controller clock frequency) + gMarvellTokenSpaceGuid.PcdI2cBaudRate|100000 + (baud rate used in I2C transmission) diff --git a/Drivers/I2c/MvI2cDxe/MvI2cDxe.c b/Drivers/I2c/MvI2cDxe/MvI2cDxe.c new file mode 100755 index 0000000..cc19aef --- /dev/null +++ b/Drivers/I2c/MvI2cDxe/MvI2cDxe.c @@ -0,0 +1,739 @@ +/******************************************************************************** +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 <Protocol/I2cMaster.h> +#include <Protocol/I2cEnumerate.h> +#include <Protocol/I2cBusConfigurationManagement.h> +#include <Protocol/DevicePath.h> + +#include <Library/BaseLib.h> +#include <Library/IoLib.h> +#include <Library/DebugLib.h> +#include <Library/PcdLib.h> +#include <Library/UefiLib.h> +#include <Library/ParsePcdLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/UefiBootServicesTableLib.h> + +#include "MvI2cDxe.h" + +STATIC MV_I2C_BAUD_RATE baud_rate; + +STATIC MV_I2C_DEVICE_PATH MvI2cDevicePathProtocol = { + { + { + HARDWARE_DEVICE_PATH, + HW_VENDOR_DP, + { + (UINT8) (sizeof(VENDOR_DEVICE_PATH)), + (UINT8) (sizeof(VENDOR_DEVICE_PATH) >> 8), + }, + }, + EFI_CALLER_ID_GUID + }, + { + END_DEVICE_PATH_TYPE, + END_ENTIRE_DEVICE_PATH_SUBTYPE, + { + sizeof(EFI_DEVICE_PATH_PROTOCOL), + 0 + } + } +}; + +STATIC +UINT32 +I2C_READ( + IN I2C_MASTER_CONTEXT *I2cMasterContext, + IN UINTN off) +{ + ASSERT (I2cMasterContext != NULL); + return MmioRead32 (I2cMasterContext->BaseAddress + off); +} + +STATIC +EFI_STATUS +I2C_WRITE ( + IN I2C_MASTER_CONTEXT *I2cMasterContext, + IN UINTN off, + IN UINT32 Value) +{ + ASSERT (I2cMasterContext != NULL); + return MmioWrite32 (I2cMasterContext->BaseAddress + off, Value); +} + +EFI_STATUS +EFIAPI +MvI2cInitialiseController ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable, + IN EFI_PHYSICAL_ADDRESS BaseAddress + ) +{ + EFI_STATUS Status; + I2C_MASTER_CONTEXT *I2cMasterContext; + STATIC INTN Bus = 0; + MV_I2C_DEVICE_PATH *DevicePath; + + DevicePath = AllocateCopyPool (sizeof(MvI2cDevicePathProtocol), + &MvI2cDevicePathProtocol); + if (DevicePath == NULL) { + DEBUG((DEBUG_ERROR, "MvI2cDxe: I2C device path allocation failed\n")); + return EFI_OUT_OF_RESOURCES; + } + DevicePath->Guid.Guid.Data4[0] = Bus; + + /* if attachment succeeds, this gets freed at ExitBootServices */ + I2cMasterContext = AllocateZeroPool (sizeof (I2C_MASTER_CONTEXT)); + if (I2cMasterContext == NULL) { + DEBUG((DEBUG_ERROR, "MvI2cDxe: I2C master context allocation failed\n")); + return EFI_OUT_OF_RESOURCES; + } + I2cMasterContext->Signature = I2C_MASTER_SIGNATURE; + I2cMasterContext->I2cMaster.Reset = MvI2cReset; + I2cMasterContext->I2cMaster.StartRequest = MvI2cStartRequest; + I2cMasterContext->I2cEnumerate.Enumerate = MvI2cEnumerate; + I2cMasterContext->I2cBusConf.EnableI2cBusConfiguration = MvI2cEnableConf; + I2cMasterContext->TclkFrequency = PcdGet32 (PcdI2cClockFrequency); + I2cMasterContext->BaseAddress = BaseAddress; + I2cMasterContext->Bus = Bus; + /* I2cMasterContext->Lock is responsible for serializing I2C operations */ + EfiInitializeLock(&I2cMasterContext->Lock, TPL_NOTIFY); + + MvI2cCalBaudRate( I2cMasterContext, + PcdGet32 (PcdI2cBaudRate), + &baud_rate, + I2cMasterContext->TclkFrequency + ); + + Status = gBS->InstallMultipleProtocolInterfaces( + &I2cMasterContext->Controller, + &gEfiI2cMasterProtocolGuid, + &I2cMasterContext->I2cMaster, + &gEfiI2cEnumerateProtocolGuid, + &I2cMasterContext->I2cEnumerate, + &gEfiI2cBusConfigurationManagementProtocolGuid, + &I2cMasterContext->I2cBusConf, + &gEfiDevicePathProtocolGuid, + (EFI_DEVICE_PATH_PROTOCOL *) DevicePath, + NULL); + + if (EFI_ERROR(Status)) { + DEBUG((DEBUG_ERROR, "MvI2cDxe: Installing protocol interfaces failed!\n")); + goto fail; + } + DEBUG((DEBUG_ERROR, "Succesfully installed controller %d at 0x%llx\n", Bus, + I2cMasterContext->BaseAddress)); + + Bus++; + + return EFI_SUCCESS; + +fail: + FreePool(I2cMasterContext); + return Status; +} + +EFI_STATUS +EFIAPI +MvI2cInitialise ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + UINT32 BusCount; + EFI_PHYSICAL_ADDRESS I2cBaseAddresses[PcdGet32 (PcdI2cBusCount)]; + INTN i; + + BusCount = PcdGet32 (PcdI2cBusCount); + if (BusCount == 0) + return EFI_SUCCESS; + + Status = ParsePcdString ( + (CHAR16 *) PcdGetPtr (PcdI2cBaseAddresses), + BusCount, + I2cBaseAddresses, + NULL + ); + if (EFI_ERROR(Status)) + return Status; + + for (i = 0; i < BusCount; i++) { + Status = MvI2cInitialiseController( + ImageHandle, + SystemTable, + I2cBaseAddresses[i] + ); + if (EFI_ERROR(Status)) + return Status; + } + + return Status; +} + +STATIC +VOID +MvI2cControlClear ( + IN I2C_MASTER_CONTEXT *I2cMasterContext, + IN UINT32 Mask) +{ + UINT32 Value; + + /* clears given bits in I2C_CONTROL register */ + Value = I2C_READ(I2cMasterContext, I2C_CONTROL); + Value &= ~Mask; + I2C_WRITE(I2cMasterContext, I2C_CONTROL, Value); +} + +STATIC +VOID +MvI2cControlSet ( + IN I2C_MASTER_CONTEXT *I2cMasterContext, + IN UINT32 Mask) +{ + UINT32 Value; + + /* sets given bits in I2C_CONTROL register */ + Value = I2C_READ(I2cMasterContext, I2C_CONTROL); + Value |= Mask; + I2C_WRITE(I2cMasterContext, I2C_CONTROL, Value); +} + +STATIC +VOID +MvI2cClearIflg ( + IN I2C_MASTER_CONTEXT *I2cMasterContext + ) +{ + gBS->Stall(I2C_OPERATION_TIMEOUT); + MvI2cControlClear(I2cMasterContext, I2C_CONTROL_IFLG); + gBS->Stall(I2C_OPERATION_TIMEOUT); +} + +/* Timeout is given in us */ +STATIC +UINTN +MvI2cPollCtrl ( + IN I2C_MASTER_CONTEXT *I2cMasterContext, + IN UINTN Timeout, + IN UINT32 Mask) +{ + Timeout /= 10; + while (!(I2C_READ(I2cMasterContext, I2C_CONTROL) & Mask)) { + gBS->Stall(10); + if (--Timeout == 0) + return (Timeout); + } + return (0); +} + +/* + * 'Timeout' is given in us. Note also that Timeout handling is not exact -- + * MvI2cLockedStart() total wait can be more than 2 x Timeout + * (MvI2cPollCtrl() is called twice). 'Mask' can be either I2C_STATUS_START + * or I2C_STATUS_RPTD_START + */ +STATIC +EFI_STATUS +MvI2cLockedStart ( + IN I2C_MASTER_CONTEXT *I2cMasterContext, + IN INT32 Mask, + IN UINT8 Slave, + IN UINTN Timeout + ) +{ + UINTN ReadAccess, IflgSet = 0; + UINT32 I2cStatus; + + if (Mask == I2C_STATUS_RPTD_START) { + /* read IFLG to know if it should be cleared later */ + IflgSet = I2C_READ(I2cMasterContext, I2C_CONTROL) & I2C_CONTROL_IFLG; + } + + MvI2cControlSet(I2cMasterContext, I2C_CONTROL_START); + + if (Mask == I2C_STATUS_RPTD_START && IflgSet) { + DEBUG((DEBUG_INFO, "MvI2cDxe: IFLG set, clearing\n")); + MvI2cClearIflg(I2cMasterContext); + } + + /* Without this delay we Timeout checking IFLG if the Timeout is 0 */ + gBS->Stall(I2C_OPERATION_TIMEOUT); + + if (MvI2cPollCtrl(I2cMasterContext, Timeout, I2C_CONTROL_IFLG)) { + DEBUG((DEBUG_ERROR, "MvI2cDxe: Timeout sending %sSTART condition\n", + Mask == I2C_STATUS_START ? "" : "repeated ")); + return EFI_NO_RESPONSE; + } + + I2cStatus = I2C_READ(I2cMasterContext, I2C_STATUS); + if (I2cStatus != Mask) { + DEBUG((DEBUG_ERROR, "MvI2cDxe: wrong I2cStatus (%02x) after sending %sSTART condition\n", + I2cStatus, Mask == I2C_STATUS_START ? "" : "repeated ")); + return EFI_DEVICE_ERROR; + } + + I2C_WRITE(I2cMasterContext, I2C_DATA, Slave); + gBS->Stall(I2C_OPERATION_TIMEOUT); + MvI2cClearIflg(I2cMasterContext); + + if (MvI2cPollCtrl(I2cMasterContext, Timeout, I2C_CONTROL_IFLG)) { + DEBUG((DEBUG_ERROR, "MvI2cDxe: Timeout sending Slave address\n")); + return EFI_NO_RESPONSE; + } + + ReadAccess = (Slave & 0x1) ? 1 : 0; + I2cStatus = I2C_READ(I2cMasterContext, I2C_STATUS); + if (I2cStatus != (ReadAccess ? + I2C_STATUS_ADDR_R_ACK : I2C_STATUS_ADDR_W_ACK)) { + DEBUG((DEBUG_ERROR, "MvI2cDxe: no ACK (I2cStatus: %02x) after sending Slave address\n", + I2cStatus)); + return EFI_NO_RESPONSE; + } + + return EFI_SUCCESS; +} + +#define ABSSUB(a,b) (((a) > (b)) ? (a) - (b) : (b) - (a)) +STATIC +VOID +MvI2cCalBaudRate ( + IN I2C_MASTER_CONTEXT *I2cMasterContext, + IN CONST UINT32 target, + IN OUT MV_I2C_BAUD_RATE *rate, + UINT32 clk + ) +{ + UINT32 cur, diff, diff0, baud; + UINTN m, n, m0, n0; + + /* Read initial m0, n0 values from register */ + baud = I2C_READ(I2cMasterContext, I2C_BAUD_RATE); + m0 = I2C_M_FROM_BAUD(baud); + n0 = I2C_N_FROM_BAUD(baud); + /* Calculate baud rate. */ + diff0 = 0xffffffff; + + for (n = 0; n < 8; n++) { + for (m = 0; m < 16; m++) { + cur = I2C_BAUD_RATE_RAW(clk,m,n); + diff = ABSSUB(target, cur); + if (diff < diff0) { + m0 = m; + n0 = n; + diff0 = diff; + } + } + } + rate->raw = I2C_BAUD_RATE_RAW(clk, m0, n0); + rate->param = I2C_BAUD_RATE_PARAM(m0, n0); + rate->m = m0; + rate->n = n0; +} + +EFI_STATUS +EFIAPI +MvI2cReset ( + IN CONST EFI_I2C_MASTER_PROTOCOL *This + ) +{ + UINT32 param; + I2C_MASTER_CONTEXT *I2cMasterContext = I2C_SC_FROM_MASTER(This); + + param = baud_rate.param; + + EfiAcquireLock (&I2cMasterContext->Lock); + I2C_WRITE(I2cMasterContext, I2C_SOFT_RESET, 0x0); + gBS->Stall(2 * I2C_OPERATION_TIMEOUT); + I2C_WRITE(I2cMasterContext, I2C_BAUD_RATE, param); + I2C_WRITE(I2cMasterContext, I2C_CONTROL, I2C_CONTROL_I2CEN | I2C_CONTROL_ACK); + gBS->Stall(I2C_OPERATION_TIMEOUT); + EfiReleaseLock (&I2cMasterContext->Lock); + + return EFI_SUCCESS; +} + +/* + * Timeout is given in us + */ +STATIC +EFI_STATUS +MvI2cRepeatedStart ( + IN I2C_MASTER_CONTEXT *I2cMasterContext, + IN UINT8 Slave, + IN UINTN Timeout + ) +{ + EFI_STATUS Status; + + EfiAcquireLock (&I2cMasterContext->Lock); + Status = MvI2cLockedStart(I2cMasterContext, I2C_STATUS_RPTD_START, Slave, + Timeout); + EfiReleaseLock (&I2cMasterContext->Lock); + + if (EFI_ERROR(Status)) { + MvI2cStop(I2cMasterContext); + } + return Status; +} + +/* + * Timeout is given in us + */ +STATIC +EFI_STATUS +MvI2cStart ( + IN I2C_MASTER_CONTEXT *I2cMasterContext, + IN UINT8 Slave, + IN UINTN Timeout + ) +{ + EFI_STATUS Status; + + EfiAcquireLock (&I2cMasterContext->Lock); + Status = MvI2cLockedStart(I2cMasterContext, I2C_STATUS_START, Slave, Timeout); + EfiReleaseLock (&I2cMasterContext->Lock); + + if (EFI_ERROR(Status)) { + MvI2cStop(I2cMasterContext); + } + return Status; +} + +STATIC +EFI_STATUS +MvI2cStop ( + IN I2C_MASTER_CONTEXT *I2cMasterContext + ) +{ + EfiAcquireLock (&I2cMasterContext->Lock); + MvI2cControlSet(I2cMasterContext, I2C_CONTROL_STOP); + gBS->Stall(I2C_OPERATION_TIMEOUT); + MvI2cClearIflg(I2cMasterContext); + EfiReleaseLock (&I2cMasterContext->Lock); + + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +MvI2cRead ( + IN I2C_MASTER_CONTEXT *I2cMasterContext, + IN OUT UINT8 *Buf, + IN UINTN Length, + IN OUT UINTN *read, + IN UINTN last, + IN UINTN delay + ) +{ + UINT32 I2cStatus; + UINTN LastByte; + EFI_STATUS Status; + + EfiAcquireLock (&I2cMasterContext->Lock); + *read = 0; + while (*read < Length) { + /* + * Check if we are reading last byte of the last Buffer, + * do not send ACK then, per I2C specs + */ + LastByte = ((*read == Length - 1) && last) ? 1 : 0; + if (LastByte) + MvI2cControlClear(I2cMasterContext, I2C_CONTROL_ACK); + else + MvI2cControlSet(I2cMasterContext, I2C_CONTROL_ACK); + + gBS->Stall (I2C_OPERATION_TIMEOUT); + MvI2cClearIflg(I2cMasterContext); + + if (MvI2cPollCtrl(I2cMasterContext, delay, I2C_CONTROL_IFLG)) { + DEBUG((DEBUG_ERROR, "MvI2cDxe: Timeout reading data\n")); + Status = EFI_NO_RESPONSE; + goto out; + } + + I2cStatus = I2C_READ(I2cMasterContext, I2C_STATUS); + if (I2cStatus != (LastByte ? + I2C_STATUS_DATA_RD_NOACK : I2C_STATUS_DATA_RD_ACK)) { + DEBUG((DEBUG_ERROR, "MvI2cDxe: wrong I2cStatus (%02x) while reading\n", I2cStatus)); + Status = EFI_DEVICE_ERROR; + goto out; + } + + *Buf++ = I2C_READ(I2cMasterContext, I2C_DATA); + (*read)++; + } + Status = EFI_SUCCESS; +out: + EfiReleaseLock (&I2cMasterContext->Lock); + return (Status); +} + +STATIC +EFI_STATUS +MvI2cWrite ( + IN I2C_MASTER_CONTEXT *I2cMasterContext, + IN OUT CONST UINT8 *Buf, + IN UINTN Length, + IN OUT UINTN *Sent, + IN UINTN Timeout + ) +{ + UINT32 status; + EFI_STATUS Status; + + EfiAcquireLock (&I2cMasterContext->Lock); + *Sent = 0; + while (*Sent < Length) { + I2C_WRITE(I2cMasterContext, I2C_DATA, *Buf++); + + MvI2cClearIflg(I2cMasterContext); + if (MvI2cPollCtrl(I2cMasterContext, Timeout, I2C_CONTROL_IFLG)) { + DEBUG((DEBUG_ERROR, "MvI2cDxe: Timeout writing data\n")); + Status = EFI_NO_RESPONSE; + goto out; + } + + status = I2C_READ(I2cMasterContext, I2C_STATUS); + if (status != I2C_STATUS_DATA_WR_ACK) { + DEBUG((DEBUG_ERROR, "MvI2cDxe: wrong status (%02x) while writing\n", status)); + Status = EFI_DEVICE_ERROR; + goto out; + } + (*Sent)++; + } + Status = EFI_SUCCESS; +out: + EfiReleaseLock (&I2cMasterContext->Lock); + return (Status); +} + +/* + * MvI2cStartRequest should be called only by I2cHost. + * I2C device drivers ought to use EFI_I2C_IO_PROTOCOL instead. + */ +STATIC +EFI_STATUS +MvI2cStartRequest ( + IN CONST EFI_I2C_MASTER_PROTOCOL *This, + IN UINTN SlaveAddress, + IN EFI_I2C_REQUEST_PACKET *RequestPacket, + IN EFI_EVENT Event OPTIONAL, + OUT EFI_STATUS *I2cStatus OPTIONAL + ) +{ + UINTN Count; + UINTN ReadMode; + UINTN Transmitted; + I2C_MASTER_CONTEXT *I2cMasterContext = I2C_SC_FROM_MASTER(This); + EFI_I2C_OPERATION *Operation; + + ASSERT (RequestPacket != NULL); + ASSERT (I2cMasterContext != NULL); + + for (Count = 0; Count < RequestPacket->OperationCount; Count++) { + Operation = &RequestPacket->Operation[Count]; + ReadMode = Operation->Flags & I2C_FLAG_READ; + + if (Count == 0) { + MvI2cStart ( I2cMasterContext, + (SlaveAddress << 1) | ReadMode, + I2C_TRANSFER_TIMEOUT + ); + } else if (!(Operation->Flags & I2C_FLAG_NORESTART)) { + MvI2cRepeatedStart ( I2cMasterContext, + (SlaveAddress << 1) | ReadMode, + I2C_TRANSFER_TIMEOUT + ); + } + + if (ReadMode) { + MvI2cRead ( I2cMasterContext, + Operation->Buffer, + Operation->LengthInBytes, + &Transmitted, + Count == 1, + I2C_TRANSFER_TIMEOUT + ); + } else { + MvI2cWrite ( I2cMasterContext, + Operation->Buffer, + Operation->LengthInBytes, + &Transmitted, + I2C_TRANSFER_TIMEOUT + ); + } + if (Count == RequestPacket->OperationCount - 1) { + MvI2cStop ( I2cMasterContext ); + } + } + + if (I2cStatus != NULL) + I2cStatus = EFI_SUCCESS; + if (Event != NULL) + gBS->SignalEvent(Event); + return EFI_SUCCESS; +} + +STATIC CONST EFI_GUID DevGuid = I2C_GUID; + +#define I2C_DEVICE_INDEX(bus, address) (((address) & 0xffff) | (bus) << 16) +#define I2C_DEVICE_ADDRESS(index) ((index) & 0xffff) + +STATIC +EFI_STATUS +MvI2cAllocDevice ( + IN UINT8 SlaveAddress, + IN UINT8 Bus, + IN OUT CONST EFI_I2C_DEVICE **Device + ) +{ + EFI_STATUS Status; + EFI_I2C_DEVICE *Dev; + UINT32 *TmpSlaveArray; + EFI_GUID *TmpGuidP; + + Status = gBS->AllocatePool ( EfiBootServicesData, + sizeof(EFI_I2C_DEVICE), + (VOID **) &Dev ); + if (EFI_ERROR(Status)) { + DEBUG((DEBUG_ERROR, "MvI2cDxe: I2C device memory allocation failed\n")); + return Status; + } + *Device = Dev; + Dev->DeviceIndex = SlaveAddress; + Dev->DeviceIndex = I2C_DEVICE_INDEX(Bus, SlaveAddress); + Dev->SlaveAddressCount = 1; + Dev->I2cBusConfiguration = 0; + Status = gBS->AllocatePool ( EfiBootServicesData, + sizeof(UINT32), + (VOID **) &TmpSlaveArray); + if (EFI_ERROR(Status)) { + goto fail1; + } + TmpSlaveArray[0] = SlaveAddress; + Dev->SlaveAddressArray = TmpSlaveArray; + + Status = gBS->AllocatePool ( EfiBootServicesData, + sizeof(EFI_GUID), + (VOID **) &TmpGuidP); + if (EFI_ERROR(Status)) { + goto fail2; + } + *TmpGuidP = DevGuid; + Dev->DeviceGuid = TmpGuidP; + + DEBUG((DEBUG_INFO, "MvI2c: allocated device with address %x\n", (UINTN)SlaveAddress)); + return EFI_SUCCESS; + +fail2: + FreePool(TmpSlaveArray); +fail1: + FreePool(Dev); + + return Status; +} + +/* + * It is called by I2cBus to enumerate devices on I2C bus. In this case, + * enumeration is based on PCD configuration - all Slave addresses specified + * in PCD get their corresponding EFI_I2C_DEVICE structures here. + * + * After enumeration succeeds, Supported() function of drivers that installed + * DriverBinding protocol is called. + */ +STATIC +EFI_STATUS +EFIAPI +MvI2cEnumerate ( + IN CONST EFI_I2C_ENUMERATE_PROTOCOL *This, + IN OUT CONST EFI_I2C_DEVICE **Device + ) +{ + UINT8 *DevicesPcd; + UINT8 *DeviceBusPcd; + UINTN Index, NextIndex; + UINT8 NextDeviceAddress; + I2C_MASTER_CONTEXT *I2cMasterContext = I2C_SC_FROM_ENUMERATE(This); + + DevicesPcd = PcdGetPtr (PcdI2cSlaveAddresses); + DeviceBusPcd = PcdGetPtr (PcdI2cSlaveBuses); + if (*Device == NULL) { + for (Index = 0; DevicesPcd[Index] != '\0'; Index++) { + if (DeviceBusPcd[Index] != I2cMasterContext->Bus) + continue; + if (DevicesPcd[Index] != '\0') + MvI2cAllocDevice (DevicesPcd[Index], I2cMasterContext->Bus, Device); + return EFI_SUCCESS; + } + } else { + /* Device is not NULL, so something was already allocated */ + for (Index = 0; DevicesPcd[Index] != '\0'; Index++) { + if (DeviceBusPcd[Index] != I2cMasterContext->Bus) + continue; + if (DevicesPcd[Index] == I2C_DEVICE_ADDRESS((*Device)->DeviceIndex)) { + for (NextIndex = Index + 1; DevicesPcd[NextIndex] != '\0'; NextIndex++) { + if (DeviceBusPcd[NextIndex] != I2cMasterContext->Bus) + continue; + NextDeviceAddress = DevicesPcd[NextIndex]; + if (NextDeviceAddress != '\0') + MvI2cAllocDevice(NextDeviceAddress, I2cMasterContext->Bus, Device); + return EFI_SUCCESS; + } + } + } + *Device = NULL; + return EFI_SUCCESS; + } + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +EFIAPI +MvI2cEnableConf ( + IN CONST EFI_I2C_BUS_CONFIGURATION_MANAGEMENT_PROTOCOL *This, + IN UINTN I2cBusConfiguration, + IN EFI_EVENT Event OPTIONAL, + IN EFI_STATUS *I2cStatus OPTIONAL + ) +{ + /* do nothing */ + if (I2cStatus != NULL) + I2cStatus = EFI_SUCCESS; + if (Event != NULL) + gBS->SignalEvent(Event); + return EFI_SUCCESS; +} diff --git a/Drivers/I2c/MvI2cDxe/MvI2cDxe.h b/Drivers/I2c/MvI2cDxe/MvI2cDxe.h new file mode 100644 index 0000000..028fd54 --- /dev/null +++ b/Drivers/I2c/MvI2cDxe/MvI2cDxe.h @@ -0,0 +1,269 @@ +/******************************************************************************** +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. + +*******************************************************************************/ + +#ifndef __MV_I2C_H__ +#define __MV_I2C_H__ + +#include <Uefi.h> + +#define I2C_BASE_ADDRESS 0xf0511000 + +#define I2C_SLAVE_ADDR 0x00 +#define I2C_EXT_SLAVE_ADDR 0x10 +#define I2C_DATA 0x04 + +#define I2C_CONTROL 0x08 +#define I2C_CONTROL_ACK (1 << 2) +#define I2C_CONTROL_IFLG (1 << 3) +#define I2C_CONTROL_STOP (1 << 4) +#define I2C_CONTROL_START (1 << 5) +#define I2C_CONTROL_I2CEN (1 << 6) +#define I2C_CONTROL_INTEN (1 << 7) + +#define I2C_STATUS 0x0c +#define I2C_STATUS_START 0x08 +#define I2C_STATUS_RPTD_START 0x10 +#define I2C_STATUS_ADDR_W_ACK 0x18 +#define I2C_STATUS_DATA_WR_ACK 0x28 +#define I2C_STATUS_ADDR_R_ACK 0x40 +#define I2C_STATUS_DATA_RD_ACK 0x50 +#define I2C_STATUS_DATA_RD_NOACK 0x58 + +#define I2C_BAUD_RATE 0x0c +#define I2C_BAUD_RATE_PARAM(M,N) ((((M) << 3) | ((N) & 0x7)) & 0x7f) +#define I2C_BAUD_RATE_RAW(C,M,N) ((C)/((10*(M+1))<<(N+1))) +#define I2C_M_FROM_BAUD(baud) (((baud) >> 3) & 0xf) +#define I2C_N_FROM_BAUD(baud) ((baud) & 0x7) + +#define I2C_SOFT_RESET 0x1c +#define I2C_TRANSFER_TIMEOUT 10000 +#define I2C_OPERATION_TIMEOUT 1000 + +#define I2C_UNKNOWN 0x0 +#define I2C_SLOW 0x1 +#define I2C_FAST 0x2 +#define I2C_FASTEST 0x3 + +/* + * I2C_FLAG_NORESTART is not part of PI spec, it allows to continue + * transmission without repeated start operation. + * FIXME: This flag is also defined in + * Platforms/Marvell/Include/Protocol/Eeprom.h and it's important to have both + * version synced. This solution is temporary and shared flag should be used by + * both files. + * Situation is analogous with I2C_GUID, which also should be common, but is + * for now defined same way in two header files. + */ +#define I2C_FLAG_NORESTART 0x00000002 +#define I2C_GUID \ + { \ + 0xadc1901b, 0xb83c, 0x4831, { 0x8f, 0x59, 0x70, 0x89, 0x8f, 0x26, 0x57, 0x1e } \ + } + +#define I2C_MASTER_SIGNATURE SIGNATURE_32 ('I', '2', 'C', 'M') + +typedef struct { + UINT32 Signature; + EFI_HANDLE Controller; + EFI_LOCK Lock; + UINTN TclkFrequency; + UINTN BaseAddress; + INTN Bus; + EFI_I2C_MASTER_PROTOCOL I2cMaster; + EFI_I2C_ENUMERATE_PROTOCOL I2cEnumerate; + EFI_I2C_BUS_CONFIGURATION_MANAGEMENT_PROTOCOL I2cBusConf; +} I2C_MASTER_CONTEXT; + +#define I2C_SC_FROM_MASTER(a) CR (a, I2C_MASTER_CONTEXT, I2cMaster, I2C_MASTER_SIGNATURE) +#define I2C_SC_FROM_ENUMERATE(a) CR (a, I2C_MASTER_CONTEXT, I2cEnumerate, I2C_MASTER_SIGNATURE) +#define I2C_SC_FROM_BUSCONF(a) CR (a, I2C_MASTER_CONTEXT, I2cBusConf, I2C_MASTER_SIGNATURE) + +typedef struct { + UINT32 raw; + UINTN param; + UINTN m; + UINTN n; +} MV_I2C_BAUD_RATE; + +typedef struct { + VENDOR_DEVICE_PATH Guid; + EFI_DEVICE_PATH_PROTOCOL End; +} MV_I2C_DEVICE_PATH; + +STATIC +UINT32 +I2C_READ( + IN I2C_MASTER_CONTEXT *I2cMasterContext, + IN UINTN off + ); + +STATIC +EFI_STATUS +I2C_WRITE ( + IN I2C_MASTER_CONTEXT *I2cMasterContext, + IN UINTN off, + IN UINT32 val + ); + +EFI_STATUS +EFIAPI +MvI2cInitialise ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +STATIC +VOID +MvI2cControlClear ( + IN I2C_MASTER_CONTEXT *I2cMasterContext, + IN UINT32 mask + ); + +STATIC +VOID +MvI2cControlSet ( + IN I2C_MASTER_CONTEXT *I2cMasterContext, + IN UINT32 mask + ); + +STATIC +VOID +MvI2cClearIflg ( + IN I2C_MASTER_CONTEXT *I2cMasterContext + ); +STATIC +UINTN +MvI2cPollCtrl ( + IN I2C_MASTER_CONTEXT *I2cMasterContext, + IN UINTN timeout, + IN UINT32 mask + ); + +STATIC +EFI_STATUS +MvI2cLockedStart ( + IN I2C_MASTER_CONTEXT *I2cMasterContext, + IN INT32 mask, + IN UINT8 slave, + IN UINTN timeout + ); + +STATIC +VOID +MvI2cCalBaudRate ( + IN I2C_MASTER_CONTEXT *I2cMasterContext, + IN CONST UINT32 target, + IN OUT MV_I2C_BAUD_RATE *rate, + UINT32 clk + ); + +EFI_STATUS +EFIAPI +MvI2cReset ( + IN CONST EFI_I2C_MASTER_PROTOCOL *This + ); + +STATIC +EFI_STATUS +MvI2cRepeatedStart ( + IN I2C_MASTER_CONTEXT *I2cMasterContext, + IN UINT8 slave, + IN UINTN timeout + ); + +STATIC +EFI_STATUS +MvI2cStart ( + IN I2C_MASTER_CONTEXT *I2cMasterContext, + IN UINT8 slave, + IN UINTN timeout + ); + +STATIC +EFI_STATUS +MvI2cStop ( + IN I2C_MASTER_CONTEXT *I2cMasterContext + ); + +STATIC +EFI_STATUS +MvI2cRead ( + IN I2C_MASTER_CONTEXT *I2cMasterContext, + IN OUT UINT8 *buf, + IN UINTN len, + IN OUT UINTN *read, + IN UINTN last, + IN UINTN delay + ); + +STATIC +EFI_STATUS +MvI2cWrite ( + IN I2C_MASTER_CONTEXT *I2cMasterContext, + IN OUT CONST UINT8 *buf, + IN UINTN len, + IN OUT UINTN *sent, + IN UINTN timeout + ); + +STATIC +EFI_STATUS +EFIAPI +MvI2cStartRequest ( + IN CONST EFI_I2C_MASTER_PROTOCOL *This, + IN UINTN SlaveAddress, + IN EFI_I2C_REQUEST_PACKET *RequestPacket, + IN EFI_EVENT Event OPTIONAL, + OUT EFI_STATUS *I2cStatus OPTIONAL + ); + +STATIC +EFI_STATUS +EFIAPI +MvI2cEnumerate ( + IN CONST EFI_I2C_ENUMERATE_PROTOCOL *This, + IN OUT CONST EFI_I2C_DEVICE **Device + ); + +STATIC +EFI_STATUS +EFIAPI +MvI2cEnableConf ( + IN CONST EFI_I2C_BUS_CONFIGURATION_MANAGEMENT_PROTOCOL *This, + IN UINTN I2cBusConfiguration, + IN EFI_EVENT Event OPTIONAL, + IN EFI_STATUS *I2cStatus OPTIONAL + ); + +#endif // __MV_I2C_H__ diff --git a/Drivers/I2c/MvI2cDxe/MvI2cDxe.inf b/Drivers/I2c/MvI2cDxe/MvI2cDxe.inf new file mode 100755 index 0000000..c7c084c --- /dev/null +++ b/Drivers/I2c/MvI2cDxe/MvI2cDxe.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 = 0x00010005 + BASE_NAME = MvI2cDxe + FILE_GUID = 59fc3843-d8d4-40aa-ae07-38967138509b + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = MvI2cInitialise + +[Sources.common] + MvI2cDxe.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + ArmPlatformPkg/ArmPlatformPkg.dec + ArmPkg/ArmPkg.dec + OpenPlatformPkg/Platforms/Marvell/Marvell.dec + +[LibraryClasses] + IoLib + PcdLib + BaseLib + DebugLib + UefiLib + UefiDriverEntryPoint + UefiBootServicesTableLib + ParsePcdLib + +[Protocols] + gEfiI2cMasterProtocolGuid + gEfiDevicePathProtocolGuid + gEfiI2cEnumerateProtocolGuid + gEfiI2cBusConfigurationManagementProtocolGuid + +[Pcd] + gMarvellTokenSpaceGuid.PcdI2cSlaveAddresses + gMarvellTokenSpaceGuid.PcdI2cSlaveBuses + gMarvellTokenSpaceGuid.PcdI2cBaseAddresses + gMarvellTokenSpaceGuid.PcdI2cClockFrequency + gMarvellTokenSpaceGuid.PcdI2cBaudRate + gMarvellTokenSpaceGuid.PcdI2cBusCount + +[Depex] + TRUE diff --git a/Platforms/Marvell/Marvell.dec b/Platforms/Marvell/Marvell.dec index fee8025..6738116 100644 --- a/Platforms/Marvell/Marvell.dec +++ b/Platforms/Marvell/Marvell.dec @@ -104,3 +104,11 @@ gMarvellTokenSpaceGuid.PcdChip3MppSel6|{ 0 }|VOID*|0x30000044 gMarvellTokenSpaceGuid.PcdChip3MppSel7|{ 0 }|VOID*|0x30000045
+#I2C + gMarvellTokenSpaceGuid.PcdI2cSlaveAddresses|{ 0 }|VOID*|0x3000046 + gMarvellTokenSpaceGuid.PcdI2cSlaveBuses|{ 0 }|VOID*|0x3000184 + gMarvellTokenSpaceGuid.PcdI2cBaseAddresses|{ 0 }|VOID*|0x3000047 + gMarvellTokenSpaceGuid.PcdI2cClockFrequency|0|UINT32|0x3000048 + gMarvellTokenSpaceGuid.PcdI2cBaudRate|0|UINT32|0x3000049 + gMarvellTokenSpaceGuid.PcdI2cBusCount|0|UINT32|0x3000183 +
From: Jan Dąbroś jsd@semihalf.com
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Bartosz Szczepanek bsz@semihalf.com Signed-off-by: Marcin Wojtas mw@semihalf.com Reviewed-by: Leif Lindholm leif.lindholm@linaro.org --- Platforms/Marvell/Armada/Armada.dsc.inc | 4 ++++ Platforms/Marvell/Armada/Armada70x0.dsc | 8 ++++++++ Platforms/Marvell/Armada/Armada70x0.fdf | 2 ++ 3 files changed, 14 insertions(+)
diff --git a/Platforms/Marvell/Armada/Armada.dsc.inc b/Platforms/Marvell/Armada/Armada.dsc.inc index 52c60f6..f32a0b0 100644 --- a/Platforms/Marvell/Armada/Armada.dsc.inc +++ b/Platforms/Marvell/Armada/Armada.dsc.inc @@ -381,6 +381,10 @@ ArmPkg/Drivers/TimerDxe/TimerDxe.inf ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.inf
+ # Platform drivers + OpenPlatformPkg/Drivers/I2c/MvI2cDxe/MvI2cDxe.inf + MdeModulePkg/Bus/I2c/I2cDxe/I2cDxe.inf + MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf diff --git a/Platforms/Marvell/Armada/Armada70x0.dsc b/Platforms/Marvell/Armada/Armada70x0.dsc index 9bd66e0..378ad20 100644 --- a/Platforms/Marvell/Armada/Armada70x0.dsc +++ b/Platforms/Marvell/Armada/Armada70x0.dsc @@ -74,3 +74,11 @@ gMarvellTokenSpaceGuid.PcdChip1MppSel4|{ 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 } gMarvellTokenSpaceGuid.PcdChip1MppSel5|{ 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0xE, 0xE, 0xE, 0xE } gMarvellTokenSpaceGuid.PcdChip1MppSel6|{ 0xE, 0xE, 0xE, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } + + # I2C + gMarvellTokenSpaceGuid.PcdI2cSlaveAddresses|{ 0x50, 0x57, 0x60 } + gMarvellTokenSpaceGuid.PcdI2cSlaveBuses|{ 0x0, 0x0, 0x0 } + gMarvellTokenSpaceGuid.PcdI2cBaseAddresses|L"0xF2701000;0xF2701100" + gMarvellTokenSpaceGuid.PcdI2cClockFrequency|250000000 + gMarvellTokenSpaceGuid.PcdI2cBaudRate|100000 + gMarvellTokenSpaceGuid.PcdI2cBusCount|2 diff --git a/Platforms/Marvell/Armada/Armada70x0.fdf b/Platforms/Marvell/Armada/Armada70x0.fdf index f42bcdd..c2026aa 100644 --- a/Platforms/Marvell/Armada/Armada70x0.fdf +++ b/Platforms/Marvell/Armada/Armada70x0.fdf @@ -102,6 +102,8 @@ FvNameGuid = 5eda4200-2c5f-43cb-9da3-0baf74b1b30c INF EmbeddedPkg/ResetRuntimeDxe/ResetRuntimeDxe.inf INF EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf INF EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf + INF OpenPlatformPkg/Drivers/I2c/MvI2cDxe/MvI2cDxe.inf + INF MdeModulePkg/Bus/I2c/I2cDxe/I2cDxe.inf
# Multiple Console IO support INF MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
From: Bartosz Szczepanek bsz@semihalf.com
MvEeprom driver produces MARVELL_EEPROM_PROTOCOL, which can be used by other drivers or applications. Working EFI_I2C_IO_PROTOCOL is required by driver to operate.
EEPROM devices' addresses need to be fed via 'PcdEepromI2cAddresses'.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Bartosz Szczepanek bsz@semihalf.com Signed-off-by: Marcin Wojtas mw@semihalf.com --- Documentation/Marvell/Drivers/EepromDriver.txt | 96 ++++++++ Drivers/I2c/Devices/MvEeprom/MvEeprom.c | 292 +++++++++++++++++++++++++ Drivers/I2c/Devices/MvEeprom/MvEeprom.h | 103 +++++++++ Drivers/I2c/Devices/MvEeprom/MvEeprom.inf | 70 ++++++ Platforms/Marvell/Include/Protocol/Eeprom.h | 60 +++++ Platforms/Marvell/Marvell.dec | 5 + 6 files changed, 626 insertions(+) create mode 100644 Documentation/Marvell/Drivers/EepromDriver.txt create mode 100644 Drivers/I2c/Devices/MvEeprom/MvEeprom.c create mode 100644 Drivers/I2c/Devices/MvEeprom/MvEeprom.h create mode 100644 Drivers/I2c/Devices/MvEeprom/MvEeprom.inf create mode 100644 Platforms/Marvell/Include/Protocol/Eeprom.h
diff --git a/Documentation/Marvell/Drivers/EepromDriver.txt b/Documentation/Marvell/Drivers/EepromDriver.txt new file mode 100644 index 0000000..e2da35f --- /dev/null +++ b/Documentation/Marvell/Drivers/EepromDriver.txt @@ -0,0 +1,96 @@ +1. Introduction +--------------- +**MvEeprom** driver creates MARVELL_EEPROM_PROTOCOL, which ++is used for managing eeprom. + +2. MvEeprom driver design +------------------------- +Every I2C device driver should implement EFI_DRIVER_BINDING_PROTOCOL and +consume EFI_I2C_IO_PROTOCOL for transactions on I2C bus. MvEeprom driver +additionally implements MARVELL_EEPROM_PROTOCOL. + + 2.1 EFI_DRIVER_BINDING_PROTOCOL + ------------------------------- + Driver Binding protocol is extensively covered in UEFI documentation, as + it is not specific to I2C stack. The only difference is that Supported() + function should check if EFI_I2C_IO_PROTOCOL provides valid EFI_GUID and + DeviceIndex values. + Excerpt from MvEepromSupported(): + + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEfiI2cIoProtocolGuid, + (VOID **) &TmpI2cIo, + gImageHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (EFI_ERROR(Status)) { + return EFI_UNSUPPORTED; + } + + /* get EEPROM devices' addresses from PCD */ + EepromAddresses = PcdGetPtr (PcdEepromI2cAddresses); + if (EepromAddresses == 0) { + Status = EFI_UNSUPPORTED; + goto out; + } + + Status = EFI_UNSUPPORTED; + for (i = 0; EepromAddresses[i] != '\0'; i++) { + /* I2C guid must fit and valid DeviceIndex must be provided */ + if (CompareGuid(TmpI2cIo->DeviceGuid, &I2cGuid) && + TmpI2cIo->DeviceIndex == EepromAddresses[i]) { + DEBUG((DEBUG_INFO, "A8kEepromSupported: attached to EEPROM device\n")); + Status = EFI_SUCCESS; + break; + } + } + + 2.2 EFI_I2C_IO_PROTOCOL + ----------------------- + This protocol is provided by generic I2C stack. Multiple drivers can use IO + protocol at once, as queueing is implemented. + + QueueRequest is a routine that queues an I2C transaction to the I2C + controller for execution on the I2C bus. + + 2.3 MARVELL_EEPROM_PROTOCOL + ----------------------- + typedef struct _MARVELL_EEPROM_PROTOCOL MARVELL_EEPROM_PROTOCOL; + + #define EEPROM_READ 0x1 + #define EEPROM_WRITE 0x0 + typedef + EFI_STATUS + (EFIAPI *EFI_EEPROM_TRANSFER) ( + IN CONST MARVELL_EEPROM_PROTOCOL *This, + IN UINT16 Address, + IN UINT32 Length, + IN UINT8 *Buffer, + IN UINT8 Operation + ); + + struct _MARVELL_EEPROM_PROTOCOL { + EFI_EEPROM_TRANSFER Transfer; + UINT8 Identifier; + }; + +3. Adding new I2C slave device drivers +-------------------------------------- +In order to support I2C slave device other than EEPROM, new driver should +be created. Required steps follow. + + 1. Create driver directory (OpenPlatformPkg/Drivers/I2c/Devices/...). + 2. Create stubs of .inf and .c files (MvEeprom files are a reference), + include .inf file in platform .dsc and .fdf files. + 3. Implement EFI_DRIVER_BINDING_PROTOCOL - Start(), Stop(), Supported() + functions' implementation is a must. EFI_DRIVER_BINDING_PROTOCOL + should be installed at driver's entry point. + 4. Add I2C address of device to PcdI2cSlaveAddresses in .dsc file. + 5. Test available EFI_I2C_IO_PROTOCOLs in Supported() - find instance + with valid GUID and DeviceIndex (I2C slave address). + 6. Open EFI_I2C_IO_PROTOCOL for usage in Start(). After that, QueueRequest + function should be available. + 7. Implement core functionality of driver (using QueueRequest to access I2C). + 8. (not mandatory) Produce/consume additional protocols. diff --git a/Drivers/I2c/Devices/MvEeprom/MvEeprom.c b/Drivers/I2c/Devices/MvEeprom/MvEeprom.c new file mode 100644 index 0000000..d8fd1bf --- /dev/null +++ b/Drivers/I2c/Devices/MvEeprom/MvEeprom.c @@ -0,0 +1,292 @@ +/******************************************************************************** +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 <Protocol/DriverBinding.h> +#include <Protocol/I2cIo.h> +#include <Protocol/Eeprom.h> + +#include <Library/BaseLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/IoLib.h> +#include <Library/DebugLib.h> +#include <Library/PcdLib.h> +#include <Library/UefiLib.h> +#include <Library/UefiBootServicesTableLib.h> + +#include <Pi/PiI2c.h> + +#include "MvEeprom.h" + +#define I2C_DEVICE_INDEX(bus, address) (((address) & 0xffff) | (bus) << 16) + +STATIC CONST EFI_GUID I2cGuid = I2C_GUID; + +EFI_DRIVER_BINDING_PROTOCOL gDriverBindingProtocol = { + MvEepromSupported, + MvEepromStart, + MvEepromStop +}; + +EFI_STATUS +EFIAPI +MvEepromSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL + ) +{ + EFI_STATUS Status = EFI_UNSUPPORTED; + EFI_I2C_IO_PROTOCOL *TmpI2cIo; + UINT8 *EepromAddresses; + UINT8 *EepromBuses; + UINTN i; + + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEfiI2cIoProtocolGuid, + (VOID **) &TmpI2cIo, + gImageHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (EFI_ERROR(Status)) { + return EFI_UNSUPPORTED; + } + + /* get EEPROM devices' addresses from PCD */ + EepromAddresses = PcdGetPtr (PcdEepromI2cAddresses); + EepromBuses = PcdGetPtr (PcdEepromI2cBuses); + if (EepromAddresses == 0) { + Status = EFI_UNSUPPORTED; + DEBUG((DEBUG_INFO, "MvEepromSupported: I2C device found, but it's not EEPROM\n")); + goto out; + } + + Status = EFI_UNSUPPORTED; + for (i = 0; EepromAddresses[i] != '\0'; i++) { + /* I2C guid must fit and valid DeviceIndex must be provided */ + if (CompareGuid(TmpI2cIo->DeviceGuid, &I2cGuid) && + TmpI2cIo->DeviceIndex == I2C_DEVICE_INDEX(EepromBuses[i], + EepromAddresses[i])) { + DEBUG((DEBUG_INFO, "MvEepromSupported: attached to EEPROM device\n")); + Status = EFI_SUCCESS; + break; + } + } + +out: + gBS->CloseProtocol ( + ControllerHandle, + &gEfiI2cIoProtocolGuid, + gImageHandle, + ControllerHandle + ); + return Status; +} + +EFI_STATUS +EFIAPI +MvEepromTransfer ( + IN CONST MARVELL_EEPROM_PROTOCOL *This, + IN UINT16 Address, + IN UINT32 Length, + IN UINT8 *Buffer, + IN UINT8 Operation + ) +{ + EFI_I2C_REQUEST_PACKET *RequestPacket; + UINTN RequestPacketSize; + EFI_STATUS Status = EFI_SUCCESS; + EEPROM_CONTEXT *EepromContext = EEPROM_SC_FROM_EEPROM(This); + UINT32 BufferLength; + UINT32 Transmitted = 0; + UINT32 CurrentAddress = Address; + + ASSERT(EepromContext != NULL); + ASSERT(EepromContext->I2cIo != NULL); + + RequestPacketSize = sizeof(UINTN) + sizeof (EFI_I2C_OPERATION) * 2; + RequestPacket = AllocateZeroPool (RequestPacketSize); + if (RequestPacket == NULL) + return EFI_OUT_OF_RESOURCES; + /* First operation contains address, the second is buffer */ + RequestPacket->OperationCount = 2; + RequestPacket->Operation[0].LengthInBytes = 2; + RequestPacket->Operation[0].Buffer = AllocateZeroPool ( RequestPacket->Operation[0].LengthInBytes ); + if (RequestPacket->Operation[0].Buffer == NULL) { + FreePool(RequestPacket); + return EFI_OUT_OF_RESOURCES; + } + RequestPacket->Operation[1].Flags = (Operation == EEPROM_READ ? I2C_FLAG_READ : I2C_FLAG_NORESTART); + + while (Length > 0) { + CurrentAddress = Address + Transmitted; + BufferLength = (Length <= MAX_BUFFER_LENGTH ? Length : MAX_BUFFER_LENGTH); + RequestPacket->Operation[0].Buffer[0] = (CurrentAddress >> 8) & 0xff; + RequestPacket->Operation[0].Buffer[1] = CurrentAddress & 0xff; + RequestPacket->Operation[1].LengthInBytes = BufferLength; + RequestPacket->Operation[1].Buffer = Buffer + Transmitted; + Status = EepromContext->I2cIo->QueueRequest(EepromContext->I2cIo, 0, NULL, RequestPacket, NULL); + if (EFI_ERROR(Status)) { + DEBUG((DEBUG_ERROR, "MvEepromTransfer: error %d during transmission\n", Status)); + break; + } + Length -= BufferLength; + Transmitted += BufferLength; + } + + FreePool(RequestPacket->Operation[0].Buffer); + FreePool(RequestPacket); + return Status; +} + +EFI_STATUS +EFIAPI +MvEepromStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL + ) +{ + EFI_STATUS Status = EFI_SUCCESS; + EEPROM_CONTEXT *EepromContext; + + EepromContext = AllocateZeroPool (sizeof(EEPROM_CONTEXT)); + if (EepromContext == NULL) { + DEBUG((DEBUG_ERROR, "MvEeprom: allocation fail\n")); + return EFI_OUT_OF_RESOURCES; + } + + EepromContext->ControllerHandle = ControllerHandle; + EepromContext->Signature = EEPROM_SIGNATURE; + EepromContext->EepromProtocol.Transfer = MvEepromTransfer; + + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEfiI2cIoProtocolGuid, + (VOID **) &EepromContext->I2cIo, + gImageHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (EFI_ERROR(Status)) { + DEBUG((DEBUG_ERROR, "MvEeprom: failed to open I2cIo\n")); + FreePool(EepromContext); + return EFI_UNSUPPORTED; + } + + EepromContext->EepromProtocol.Identifier = EepromContext->I2cIo->DeviceIndex; + Status = gBS->InstallMultipleProtocolInterfaces ( + &ControllerHandle, + &gMarvellEepromProtocolGuid, &EepromContext->EepromProtocol, + NULL + ); + if (EFI_ERROR(Status)) { + DEBUG((DEBUG_ERROR, "MvEeprom: failed to install EEPROM protocol\n")); + goto fail; + } + + return Status; + +fail: + FreePool(EepromContext); + gBS->CloseProtocol ( + ControllerHandle, + &gEfiI2cIoProtocolGuid, + gImageHandle, + ControllerHandle + ); + + return Status; +} + +EFI_STATUS +EFIAPI +MvEepromStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer OPTIONAL + ) +{ + MARVELL_EEPROM_PROTOCOL *EepromProtocol; + EFI_STATUS Status; + EEPROM_CONTEXT *EepromContext; + + Status = gBS->OpenProtocol ( + ControllerHandle, + &gMarvellEepromProtocolGuid, + (VOID **) &EepromProtocol, + This->DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + EepromContext = EEPROM_SC_FROM_EEPROM(EepromProtocol); + + gBS->UninstallMultipleProtocolInterfaces ( + &ControllerHandle, + &gMarvellEepromProtocolGuid, &EepromContext->EepromProtocol, + &gEfiDriverBindingProtocolGuid, &gDriverBindingProtocol, + NULL + ); + gBS->CloseProtocol ( + ControllerHandle, + &gEfiI2cIoProtocolGuid, + gImageHandle, + ControllerHandle + ); + FreePool(EepromContext); + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +MvEepromInitialise ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + Status = gBS->InstallMultipleProtocolInterfaces ( + &ImageHandle, + &gEfiDriverBindingProtocolGuid, &gDriverBindingProtocol, + NULL + ); + return Status; +} diff --git a/Drivers/I2c/Devices/MvEeprom/MvEeprom.h b/Drivers/I2c/Devices/MvEeprom/MvEeprom.h new file mode 100644 index 0000000..b1af645 --- /dev/null +++ b/Drivers/I2c/Devices/MvEeprom/MvEeprom.h @@ -0,0 +1,103 @@ +/******************************************************************************** +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. + +*******************************************************************************/ + +#ifndef __MV_EEPROM_H__ +#define __MV_EEPROM_H__ + +#include <Uefi.h> + +#define EEPROM_SIGNATURE SIGNATURE_32 ('E', 'E', 'P', 'R') + +#define MAX_BUFFER_LENGTH 64 + +/* + * I2C_FLAG_NORESTART is not part of PI spec, it allows to continue + * transmission without repeated start operation. + * FIXME: This flag is also defined in Drivers/I2c/MvI2cDxe/MvI2cDxe.h + * and it's important to have both version synced. This solution is + * temporary and shared flag should be used by both files. + * Situation is analogous with I2C_GUID, which also should be common, but is + * for now defined same way in two header files. + */ +#define I2C_FLAG_NORESTART 0x00000002 +#define I2C_GUID \ + { \ + 0xadc1901b, 0xb83c, 0x4831, { 0x8f, 0x59, 0x70, 0x89, 0x8f, 0x26, 0x57, 0x1e } \ + } + +typedef struct { + UINT32 Signature; + EFI_HANDLE ControllerHandle; + EFI_I2C_IO_PROTOCOL *I2cIo; + MARVELL_EEPROM_PROTOCOL EepromProtocol; +} EEPROM_CONTEXT; + +#define EEPROM_SC_FROM_IO(a) CR (a, EEPROM_CONTEXT, I2cIo, EEPROM_SIGNATURE) +#define EEPROM_SC_FROM_EEPROM(a) CR (a, EEPROM_CONTEXT, EepromProtocol, EEPROM_SIGNATURE) + +EFI_STATUS +EFIAPI +MvEepromSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL + ); + +EFI_STATUS +EFIAPI +MvEepromStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL + ); + +EFI_STATUS +EFIAPI +MvEepromStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer OPTIONAL + ); + +EFI_STATUS +EFIAPI +MvEepromTransfer ( + IN CONST MARVELL_EEPROM_PROTOCOL *This, + IN UINT16 Address, + IN UINT32 Length, + IN UINT8 *Buffer, + IN UINT8 Operation + ); +#endif // __MV_EEPROM_H__ diff --git a/Drivers/I2c/Devices/MvEeprom/MvEeprom.inf b/Drivers/I2c/Devices/MvEeprom/MvEeprom.inf new file mode 100644 index 0000000..219041b --- /dev/null +++ b/Drivers/I2c/Devices/MvEeprom/MvEeprom.inf @@ -0,0 +1,70 @@ +# +# 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 = 0x00010005 + BASE_NAME = MvEeprom + FILE_GUID = 59fc3843-d8d4-40aa-ae07-38967138509c + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = MvEepromInitialise + +[Sources.common] + MvEeprom.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + ArmPlatformPkg/ArmPlatformPkg.dec + ArmPkg/ArmPkg.dec + OpenPlatformPkg/Platforms/Marvell/Marvell.dec + +[LibraryClasses] + IoLib + PcdLib + BaseLib + BaseMemoryLib + DebugLib + UefiLib + UefiDriverEntryPoint + UefiBootServicesTableLib + +[Protocols] + gEfiI2cIoProtocolGuid + gEfiDriverBindingProtocolGuid + gMarvellEepromProtocolGuid + +[Pcd] + gMarvellTokenSpaceGuid.PcdEepromI2cAddresses + gMarvellTokenSpaceGuid.PcdEepromI2cBuses + +[Depex] + TRUE diff --git a/Platforms/Marvell/Include/Protocol/Eeprom.h b/Platforms/Marvell/Include/Protocol/Eeprom.h new file mode 100644 index 0000000..2708f7d --- /dev/null +++ b/Platforms/Marvell/Include/Protocol/Eeprom.h @@ -0,0 +1,60 @@ +/******************************************************************************** +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. + +*******************************************************************************/ + +#ifndef __MARVELL_EEPROM_H__ +#define __MARVELL_EEPROM_H__ + +#define MARVELL_EEPROM_PROTOCOL_GUID { 0xcd728a1f, 0x45b5, 0x4feb, { 0x98, 0xc8, 0x31, 0x3d, 0xa8, 0x11, 0x74, 0x62 }} + +typedef struct _MARVELL_EEPROM_PROTOCOL MARVELL_EEPROM_PROTOCOL; + +#define EEPROM_READ 0x1 +#define EEPROM_WRITE 0x0 +typedef +EFI_STATUS +(EFIAPI *EFI_EEPROM_TRANSFER) ( + IN CONST MARVELL_EEPROM_PROTOCOL *This, + IN UINT16 Address, + IN UINT32 Length, + IN UINT8 *Buffer, + IN UINT8 Operation + ); + +struct _MARVELL_EEPROM_PROTOCOL { + EFI_EEPROM_TRANSFER Transfer; + UINT32 Identifier; +}; + +extern EFI_GUID gMarvellEepromProtocolGuid; +#endif diff --git a/Platforms/Marvell/Marvell.dec b/Platforms/Marvell/Marvell.dec index 6738116..bc4ac7a 100644 --- a/Platforms/Marvell/Marvell.dec +++ b/Platforms/Marvell/Marvell.dec @@ -107,8 +107,13 @@ #I2C gMarvellTokenSpaceGuid.PcdI2cSlaveAddresses|{ 0 }|VOID*|0x3000046 gMarvellTokenSpaceGuid.PcdI2cSlaveBuses|{ 0 }|VOID*|0x3000184 + gMarvellTokenSpaceGuid.PcdEepromI2cAddresses|{ 0 }|VOID*|0x3000050 + gMarvellTokenSpaceGuid.PcdEepromI2cBuses|{ 0 }|VOID*|0x3000185 gMarvellTokenSpaceGuid.PcdI2cBaseAddresses|{ 0 }|VOID*|0x3000047 gMarvellTokenSpaceGuid.PcdI2cClockFrequency|0|UINT32|0x3000048 gMarvellTokenSpaceGuid.PcdI2cBaudRate|0|UINT32|0x3000049 gMarvellTokenSpaceGuid.PcdI2cBusCount|0|UINT32|0x3000183
+[Protocols] + gMarvellEepromProtocolGuid = { 0xcd728a1f, 0x45b5, 0x4feb, { 0x98, 0xc8, 0x31, 0x3d, 0xa8, 0x11, 0x74, 0x62 }} +
From: Jan Dąbroś jsd@semihalf.com
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Bartosz Szczepanek bsz@semihalf.com Signed-off-by: Marcin Wojtas mw@semihalf.com Reviewed-by: Leif Lindholm leif.lindholm@linaro.org --- Platforms/Marvell/Armada/Armada.dsc.inc | 1 + Platforms/Marvell/Armada/Armada70x0.dsc | 2 ++ Platforms/Marvell/Armada/Armada70x0.fdf | 1 + 3 files changed, 4 insertions(+)
diff --git a/Platforms/Marvell/Armada/Armada.dsc.inc b/Platforms/Marvell/Armada/Armada.dsc.inc index f32a0b0..dc4700a 100644 --- a/Platforms/Marvell/Armada/Armada.dsc.inc +++ b/Platforms/Marvell/Armada/Armada.dsc.inc @@ -384,6 +384,7 @@ # Platform drivers OpenPlatformPkg/Drivers/I2c/MvI2cDxe/MvI2cDxe.inf MdeModulePkg/Bus/I2c/I2cDxe/I2cDxe.inf + OpenPlatformPkg/Drivers/I2c/Devices/MvEeprom/MvEeprom.inf
MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf diff --git a/Platforms/Marvell/Armada/Armada70x0.dsc b/Platforms/Marvell/Armada/Armada70x0.dsc index 378ad20..76b06e0 100644 --- a/Platforms/Marvell/Armada/Armada70x0.dsc +++ b/Platforms/Marvell/Armada/Armada70x0.dsc @@ -79,6 +79,8 @@ gMarvellTokenSpaceGuid.PcdI2cSlaveAddresses|{ 0x50, 0x57, 0x60 } gMarvellTokenSpaceGuid.PcdI2cSlaveBuses|{ 0x0, 0x0, 0x0 } gMarvellTokenSpaceGuid.PcdI2cBaseAddresses|L"0xF2701000;0xF2701100" + gMarvellTokenSpaceGuid.PcdEepromI2cAddresses|{ 0x50, 0x57 } + gMarvellTokenSpaceGuid.PcdEepromI2cBuses|{ 0x0, 0x0 } gMarvellTokenSpaceGuid.PcdI2cClockFrequency|250000000 gMarvellTokenSpaceGuid.PcdI2cBaudRate|100000 gMarvellTokenSpaceGuid.PcdI2cBusCount|2 diff --git a/Platforms/Marvell/Armada/Armada70x0.fdf b/Platforms/Marvell/Armada/Armada70x0.fdf index c2026aa..552cb35 100644 --- a/Platforms/Marvell/Armada/Armada70x0.fdf +++ b/Platforms/Marvell/Armada/Armada70x0.fdf @@ -104,6 +104,7 @@ FvNameGuid = 5eda4200-2c5f-43cb-9da3-0baf74b1b30c INF EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf INF OpenPlatformPkg/Drivers/I2c/MvI2cDxe/MvI2cDxe.inf INF MdeModulePkg/Bus/I2c/I2cDxe/I2cDxe.inf + INF OpenPlatformPkg/Drivers/I2c/Devices/MvEeprom/MvEeprom.inf
# Multiple Console IO support INF MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
From: Bartosz Szczepanek bsz@semihalf.com
'eeprom' command brings MvEeprom driver capabilities to UEFI shell. It allows reading & writing from/to onboard EEPROM device.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Bartosz Szczepanek bsz@semihalf.com Signed-off-by: Marcin Wojtas mw@semihalf.com Reviewed-by: Leif Lindholm leif.lindholm@linaro.org --- Applications/EepromCmd/EepromCmd.c | 397 +++++++++++++++++++++++++++++++++++ Applications/EepromCmd/EepromCmd.inf | 71 +++++++ Applications/EepromCmd/EepromCmd.uni | Bin 0 -> 6816 bytes Platforms/Marvell/Marvell.dec | 2 + 4 files changed, 470 insertions(+) create mode 100644 Applications/EepromCmd/EepromCmd.c create mode 100644 Applications/EepromCmd/EepromCmd.inf create mode 100644 Applications/EepromCmd/EepromCmd.uni
diff --git a/Applications/EepromCmd/EepromCmd.c b/Applications/EepromCmd/EepromCmd.c new file mode 100644 index 0000000..f43e411 --- /dev/null +++ b/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/Applications/EepromCmd/EepromCmd.inf b/Applications/EepromCmd/EepromCmd.inf new file mode 100644 index 0000000..1171fc1 --- /dev/null +++ b/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 + OpenPlatformPkg/Platforms/Marvell/Marvell.dec + +[LibraryClasses] + UefiLib + UefiBootServicesTableLib + MemoryAllocationLib + BaseLib + BaseMemoryLib + DebugLib + ShellCommandLib + ShellLib + UefiLib + UefiRuntimeServicesTableLib + PcdLib + +[Protocols] + gMarvellEepromProtocolGuid + gEfiI2cMasterProtocolGuid + +[Guids] + gShellEepromHiiGuid diff --git a/Applications/EepromCmd/EepromCmd.uni b/Applications/EepromCmd/EepromCmd.uni new file mode 100644 index 0000000000000000000000000000000000000000..e41c6d812ef5d8e3b23c54e5fcbee017507b5c2f GIT binary patch literal 6816 zcmd6rZEsUY5QX=1rT&Mj@P#50L#wtDrIj4Vfk@6vZHE*=g%UfVmSQKhO@Tk(_B=bD z?C!OlP^3!8^1b^ybLQ;K?C$;N??!m=MgP7IUxik<3fJLdn1)e!8~zCMP=)(y{YLL^ z!=vyx{Gif)IMs;1!g;vVuL^r%qLJrno2X~5xmU47Uq|&}*a}GJU!S`jdSNGy8-;;n zOu|ghDjW)jOY*sU;X*whCH<Y=Q;lQBC?XlEWiG@c&9B0)-j`9%g~nZlvD!+_57pw5 z#zOs3b!^Atxk{CEfP`^q8b--;l}F)Beb`%R-b6hOjh{yA#ws!LBFbBZ=UtouSB4iU z7n%i=SK+<pPQ-krTH?dojN`Fz8K2#ixQu<r=5|z3a;3SjH;v4tF=w%tRfPxeOvTwO zS`Q{HfgezN9XYU-YzA>!|A&zgWMbpBp2$QNcCcR8YPr(tja0K1^dRAOZU&kK@5nN1 zS##GkmaKVra^rE8`tsic)ox=BSy$21O0LifPAtYZK#6U0X=a5I=2LkHb}^P&^@y6N z4di&Qv6SQUa`GO0!Sorfb@szaLb1xL%!>!|E-=H?G>c8w?C(!u$}C^)KXs;Ty@z5C z%M;Su`6BuqQT{GjG-($7|1V!2NvzL#^s*e4mxo&8fh>h%vSW%1k2=d5_?k%~w#Y;l z<s+3Ywd$*)#3L{<xSX9VE>hlgT>fTl4}{HPyUa&qad3Mal$o=VJ(dX!H+37IA_u9| z%v1BM$xM1Y=bqidp=Dt6X)-cQ!YdLC9h{k0k%cTL=U!$gh+6VC5s9?4C!`o7)-NRC zy=<|J<t$sCTjzzdnArxBexd(hfd}?2SEAQ49vLEK!I^BRuTeid*IwGwxSsaE-Ovvw zp{ZQeR*SVCsdgA%sJ5fl9kp+VmwGajQ7!czsimtC&(zje+jF&b;`nZq-PF1>ld%UH z!PxC^tkR*%Xy1@l-ss%W+h)K3CG@q!Z_)#@UL46x#_y}Oqqku*^xZhCA6t8IN7<8< zmc|_m2jyq6)iB_dhY>e&_Vw>Cq=Ap!*ljJffo_#PP7=GCwJ#}MX??yx)0EA75o<qM z<gDyQjR!ZD?M7DMpptE@29~shy%TG+9;@|8<9eFKNO%Dc*7c&LO_e~fqihRL2YO;B zOuo>cbzs#&*U>LoxoSlZWhn^Z+?Zd#mfIS~DQr)YxAmrGHs$LHQc$;q1CBwss;#9S zJP*7eWo%EjGZPKgf_JnRz5p99<G36tO#Ld}Op?v4B)O?sP5A?U1-|<c$>;lu#S5#2 zb*z9fZ9dUcJLgYUw68LrR!RGzemiP+c0t>XQP)zb7k-M^IvVBPkB1$r){d592mHW} zS#3DXx0vtk_<S$g=#d2T;OOdiEM~z*oN@vul26o!$FTM-=`gLtvwJY3^R=~j0SA$5 zmb*Ws2mtGeG_<9Wr^PdVntZEy;~#KF-oRgyca_r2a?2|HwW~=Sw8c4ySa&i5t6;Oq z1cv5B{qPG9_!KqE9Uf1fo5%uYDJ$w0d)6?%@>V3lS3T##h({+nSmUPrg6s<tI5#$3 zw&ehDmANH(8~La7^Rz>M*|)<+<OrS`;pcGgrgkr$CAqV(%W^;C$4<Q&eUsgU+S_=e znd!{5k<H~)%MNLG9`mX<(GU9JO<ehoV&IL~ZtKn7x4+Qf=a}?PNZx4=e=DtZ9Hx0g zIhYlr_x$GcQ0aCH)@{vYXJ#iawQ`mj$8!s(kS&dUE$pv_J;^15<I&`?_EJB$j#JHT z=#*jS0x%BM#`!RvOB#_8yM?w3jGW3i>2Ob5r@bfdXKy)*5z<>4S1q-aJiL;0!}+@~ zy~?m!-A~t6+Y}xvJyqm#|Go~t+_W@h-7w1IyhD2(by`14ufkJh0`nKnW-e({QY!WB zEVxSTv)JAfCw{A4rDaQ8urjdX8TC_`0h6;)BK6v4F(RETbKl8*gn9YuyPWh!Vm`uc z=Csc#IG0S00^gsqezf4ZQsfQAbMi}M`>G{9c?q3q#Hmio+z+`Wp6Q8~=34RD^LTIP z9yg1+>iY1DTtit#ACb@ZlbN!H-9MbY#==rgj{6#!d;L0#SEF!`EVX+L6s28!*}<cT z(&V>w+e)u?Y5qoPIp1%Lr7l}d_pUrA)b%9~a2@#@eJO{WDKpqT$mDasO8!L8WXU)3 zh|48g8Tt4CIhvUCTVc|<-jYVV0rLH$Zc`qyt98~nv~M3tt9^NJAIYt?Z!RNYF5|$n z0OwOYi@OTvuH~FmZ>i6CvNWfoc(HFZWo#^utnWJ>cXgdz;fI52@zvE=7XS1}S@yI? z;X~ZXjGe(EBeT1G2;YYv^<Av4r;f)xGR?6P`y)~w>sgm!-&-$NV)c8p%_gIOdLEy7 zlqD^nk3G+uZgG<9=q*DgJaubY%Cq=v6~5C~?@EX*rb_0K#y9cw^EfYkGLQPZ*}vNY zbYj6+&t(jsXG@OJ_ZhR|Zp3%_%YVb`G0J_7J6Ts}nHP#yz7~91tmZSTV(uzi?AG0u z{Ep6<+z4Co24Xk6GBfoRO=QzkWi|iuOm5}GXy3ZV@*8p`d6vkv9vEVWX0NoKt)&P; x6K51h!fl;9kbnIsk+ijU^6h-8S?^<v+b(V2zHC?K6l>?|^5j~22q${}{{kxp-hluB
literal 0 HcmV?d00001
diff --git a/Platforms/Marvell/Marvell.dec b/Platforms/Marvell/Marvell.dec index bc4ac7a..a9c5a12 100644 --- a/Platforms/Marvell/Marvell.dec +++ b/Platforms/Marvell/Marvell.dec @@ -52,6 +52,8 @@ [Guids.common] gMarvellTokenSpaceGuid = { 0xf995c6c8, 0xbc9b, 0x4e93, { 0xbd, 0xcf, 0x49, 0x90, 0xc6, 0xe7, 0x8c, 0x7f } }
+ gShellEepromHiiGuid = { 0xb2f4c714, 0x147f, 0x4ff7, { 0x82, 0x1b, 0xce, 0x7b, 0x91, 0x7f, 0x5f, 0x2f } } + [PcdsFixedAtBuild.common] #MPP gMarvellTokenSpaceGuid.PcdMppChipCount|0|UINT32|0x30000001
From: Jan Dąbroś jsd@semihalf.com
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Bartosz Szczepanek bsz@semihalf.com Signed-off-by: Marcin Wojtas mw@semihalf.com Reviewed-by: Leif Lindholm leif.lindholm@linaro.org --- Platforms/Marvell/Armada/Armada.dsc.inc | 1 + 1 file changed, 1 insertion(+)
diff --git a/Platforms/Marvell/Armada/Armada.dsc.inc b/Platforms/Marvell/Armada/Armada.dsc.inc index dc4700a..b5b5744 100644 --- a/Platforms/Marvell/Armada/Armada.dsc.inc +++ b/Platforms/Marvell/Armada/Armada.dsc.inc @@ -433,6 +433,7 @@ NULL|ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1CommandsLib.inf NULL|ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1CommandsLib.inf NULL|ShellPkg/Library/UefiShellTftpCommandLib/UefiShellTftpCommandLib.inf + NULL|OpenPlatformPkg/Applications/EepromCmd/EepromCmd.inf HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.inf
From: Jan Dąbroś jsd@semihalf.com
Add MARVELL_SPI_MASTER_PROTOCOL and register its GUID in Marvell.dec file in order to make it public.
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 --- Platforms/Marvell/Include/Protocol/Spi.h | 105 +++++++++++++++++++++++++++++++ Platforms/Marvell/Marvell.dec | 1 + 2 files changed, 106 insertions(+) create mode 100644 Platforms/Marvell/Include/Protocol/Spi.h
diff --git a/Platforms/Marvell/Include/Protocol/Spi.h b/Platforms/Marvell/Include/Protocol/Spi.h new file mode 100644 index 0000000..ae78a31 --- /dev/null +++ b/Platforms/Marvell/Include/Protocol/Spi.h @@ -0,0 +1,105 @@ +/******************************************************************************* +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. + +*******************************************************************************/ +#ifndef __MARVELL_SPI_MASTER_PROTOCOL_H__ +#define __MARVELL_SPI_MASTER_PROTOCOL_H__ + +extern EFI_GUID gMarvellSpiMasterProtocolGuid; + +typedef struct _MARVELL_SPI_MASTER_PROTOCOL MARVELL_SPI_MASTER_PROTOCOL; + +typedef enum { + SPI_MODE0, // CPOL = 0 & CPHA = 0 + SPI_MODE1, // CPOL = 0 & CPHA = 1 + SPI_MODE2, // CPOL = 1 & CPHA = 0 + SPI_MODE3 // CPOL = 1 & CPHA = 1 +} SPI_MODE; + +typedef struct { + INTN Cs; + INTN MaxFreq; + SPI_MODE Mode; +} SPI_DEVICE; + +typedef +EFI_STATUS +(EFIAPI *MV_SPI_INIT) ( + IN MARVELL_SPI_MASTER_PROTOCOL *This + ); + +typedef +EFI_STATUS +(EFIAPI *MV_SPI_TRANSFER) ( + IN MARVELL_SPI_MASTER_PROTOCOL *This, + IN SPI_DEVICE *Slave, + IN UINTN DataByteCount, + IN VOID *DataOut, + IN VOID *DataIn, + IN UINTN Flag + ); + +typedef +EFI_STATUS +(EFIAPI * MV_SPI_READ_WRITE) ( + IN MARVELL_SPI_MASTER_PROTOCOL *This, + IN SPI_DEVICE *Slave, + IN UINT8 *Cmd, + IN UINTN CmdSize, + IN UINT8 *DataOut, + OUT UINT8 *DataIn, + IN UINTN DataSize + ); + +typedef +SPI_DEVICE * +(EFIAPI *MV_SPI_SETUP_DEVICE) ( + IN MARVELL_SPI_MASTER_PROTOCOL *This, + IN UINTN Cs, + IN SPI_MODE Mode + ); + +typedef +EFI_STATUS +(EFIAPI *MV_SPI_FREE_DEVICE) ( + IN SPI_DEVICE *SpiDev + ); + +struct _MARVELL_SPI_MASTER_PROTOCOL { + MV_SPI_INIT Init; + MV_SPI_READ_WRITE ReadWrite; + MV_SPI_TRANSFER Transfer; + MV_SPI_SETUP_DEVICE SetupDevice; + MV_SPI_FREE_DEVICE FreeDevice; +}; + +#endif // __MARVELL_SPI_MASTER_PROTOCOL_H__ diff --git a/Platforms/Marvell/Marvell.dec b/Platforms/Marvell/Marvell.dec index a9c5a12..dc670e7 100644 --- a/Platforms/Marvell/Marvell.dec +++ b/Platforms/Marvell/Marvell.dec @@ -118,4 +118,5 @@
[Protocols] gMarvellEepromProtocolGuid = { 0xcd728a1f, 0x45b5, 0x4feb, { 0x98, 0xc8, 0x31, 0x3d, 0xa8, 0x11, 0x74, 0x62 }} + gMarvellSpiMasterProtocolGuid = { 0x23de66a3, 0xf666, 0x4b3e, { 0xaa, 0xa2, 0x68, 0x9b, 0x18, 0xae, 0x2e, 0x19 }}
From: Jan Dąbroś jsd@semihalf.com
Spi master driver implements MARVELL_SPI_MASTER_PROTOCOL. It configures and manages SPI controller.
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 --- Documentation/Marvell/Drivers/SpiDriver.txt | 116 +++++++++ Documentation/Marvell/PortingGuide/Spi.txt | 15 ++ Drivers/Spi/MvSpiDxe.c | 379 ++++++++++++++++++++++++++++ Drivers/Spi/MvSpiDxe.h | 145 +++++++++++ Drivers/Spi/MvSpiDxe.inf | 66 +++++ Platforms/Marvell/Marvell.dec | 5 + 6 files changed, 726 insertions(+) create mode 100644 Documentation/Marvell/Drivers/SpiDriver.txt create mode 100644 Documentation/Marvell/PortingGuide/Spi.txt create mode 100755 Drivers/Spi/MvSpiDxe.c create mode 100644 Drivers/Spi/MvSpiDxe.h create mode 100644 Drivers/Spi/MvSpiDxe.inf
diff --git a/Documentation/Marvell/Drivers/SpiDriver.txt b/Documentation/Marvell/Drivers/SpiDriver.txt new file mode 100644 index 0000000..42b5e3c --- /dev/null +++ b/Documentation/Marvell/Drivers/SpiDriver.txt @@ -0,0 +1,116 @@ +1. Introduction +--------------- +**SpiDxe** driver implements MARVELL_SPI_MASTER_PROTOCOL in order to manage SPI +controller on Marvell A8k boards. It exposes below functionalities: + - create and setup SPI slaves + - raw transfer over SPI bus + +2. SpiDxe driver design +----------------------- + + 2.1 MARVELL_SPI_MASTER_PROTOCOL + ----------------------- + First member of SPI_MASTER protocol is Init function, implemented for SPI + master controller initialization. + + ->Init() + + // + //Initializes the host controller to execute SPI commands. + // + + param[IN] This Pointer to the MARVELL_SPI_MASTER_PROTOCOL instance + + return EFI_SUCCESS Opcode initialization on the SPI host + controller completed. + return EFI_ACCESS_DENIED The SPI configuration interface is + locked. + return EFI_OUT_OF_RESOURCES Not enough resource available to + initialize the device. + return EFI_DEVICE_ERROR Device error, operation failed. + + ******** + + SPI devices (slaves) do not support any kind of automatic discovery or + enumaration, so every device needs manual configuration, which may be done + with SetupDevice function. + + ->SetupDevice() + + // + //Allocate and zero all fields in the SPI_DEVICE struct. Set the chip + //select, max frequency and transfer mode supported by slave device. + // + + param[IN] Cs Chip select ID of the slave chip. + param[IN] MaxFreq Maximum SCK rate in Hz. + param[IN] Mode Clock polarity and clock phase. + + return *SPI_DEVICE Pointer to new allocated struct SPI_DEVICE. + return NULL NULL pointer if any eroor occured. + + ******** + + Developers have to destroy all created SPI device structs (with FreeDevice + function) in order to prevent from memory leak. + + ->FreeDevice() + + // + //Free any memory associated with a SPI device. + // + + param[in] SpiDev Pointer to the SPI_DEVICE struct. + + return EFI_SUCCESS Memory fried succesfully. + return EFI_DEVICE_ERROR Device error, operation failed. + + ******** + + Transfer function allows write/read raw bytes over SPI bus. + + ->Transfer() + + // + //Perform transfer over SPI bus + // + param[in] This Pointer to the MARVELL_SPI_MASTER_PROTOCOL + instance. + param[in] Slave Pointer to the SPI_DEVICE struct. + param[in] DataByteCount Number of bytes in the data portion of + the SPI cycle. + param[in] DataOut Pointer to caller-allocated buffer + containing the data to send. + param[out] DataIn Pointer to caller-allocated buffer + where received data will be placed. + param[in] Flag Flags which indicate state of CS line + during/after transfer (see file + Drivers/Spi/Devices/A8kSpiFlash.h) + + return EFI_SUCCESS Memory fried succesfully. + return EFI_DEVICE_ERROR Device error, operation failed. + + ********* + + When working with SPI devices it is often necessary to perform "command and + address" transactions. It may be done via ReadWrite function. + + ->ReadWrite() + + // + //Perform two steps transactions. First write Command, then read/write + //buffer + // + + param[in] This Pointer to the MARVELL_SPI_MASTER_PROTOCOL + instance. + param[in] Slave Pointer to the SPI_DEVICE struct. + param[in] Cmd Pointer to caller-allocated buffer + containing the command to send. + param[in] CmdSize Size of command (in bytes). + param[in] DataOut Pointer to caller-allocated buffer + containing the data to send. + param[out] DataIn Pointer to caller-allocated buffer + where received data will be placed. + param[in] DataSize Number of bytes in the data portion of + the SPI cycle. diff --git a/Documentation/Marvell/PortingGuide/Spi.txt b/Documentation/Marvell/PortingGuide/Spi.txt new file mode 100644 index 0000000..f1f36ad --- /dev/null +++ b/Documentation/Marvell/PortingGuide/Spi.txt @@ -0,0 +1,15 @@ +Spi driver configuration +------------------------ +Following PCDs are available for configuration of spi driver: + + gMarvellTokenSpaceGuid.PcdSpiClockFrequency + +Frequency (in Hz) of SPI clock + + gMarvellTokenSpaceGuid.PcdSpiMaxFrequency + +Max SCLK line frequency (in Hz) (max transfer frequency) + + gMarvellTokenSpaceGuid.PcdSpiDefaultMode + +default SCLK mode (see SPI_MODE enum in file OpenPlatformPkg/Drivers/Spi/MvSpi.h) diff --git a/Drivers/Spi/MvSpiDxe.c b/Drivers/Spi/MvSpiDxe.c new file mode 100755 index 0000000..aab20fc --- /dev/null +++ b/Drivers/Spi/MvSpiDxe.c @@ -0,0 +1,379 @@ +/******************************************************************************* +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 "MvSpiDxe.h" + +SPI_MASTER *mSpiMasterInstance; + +STATIC +EFI_STATUS +SpiSetBaudRate ( + IN UINT32 CpuClock, + IN UINT32 MaxFreq + ) +{ + UINT32 Spr, BestSpr, Sppr, BestSppr, ClockDivider, Match, Reg, MinBaudDiff; + UINTN SpiRegBase = PcdGet32 (PcdSpiRegBase); + + MinBaudDiff = 0xFFFFFFFF; + BestSppr = 0; + + //Spr is in range 1-15 and Sppr in range 0-8 + for (Spr = 1; Spr <= 15; Spr++) { + for (Sppr = 0; Sppr <= 7; Sppr++) { + ClockDivider = Spr * (1 << Sppr); + + if ((CpuClock / ClockDivider) > MaxFreq) { + continue; + } + + if ((CpuClock / ClockDivider) == MaxFreq) { + BestSpr = Spr; + BestSppr = Sppr; + Match = 1; + break; + } + + if ((MaxFreq - (CpuClock / ClockDivider)) < MinBaudDiff) { + MinBaudDiff = (MaxFreq - (CpuClock / ClockDivider)); + BestSpr = Spr; + BestSppr = Sppr; + } + } + + if (Match == 1) { + break; + } + } + + if (BestSpr == 0) { + return (EFI_INVALID_PARAMETER); + } + + Reg = MmioRead32 (SpiRegBase + SPI_CONF_REG); + Reg &= ~(SPI_SPR_MASK | SPI_SPPR_0_MASK | SPI_SPPR_HI_MASK); + Reg |= (BestSpr << SPI_SPR_OFFSET) | + ((BestSppr & 0x1) << SPI_SPPR_0_OFFSET) | + ((BestSppr >> 1) << SPI_SPPR_HI_OFFSET); + MmioWrite32 (SpiRegBase + SPI_CONF_REG, Reg); + + return EFI_SUCCESS; +} + +STATIC +VOID +SpiSetCs ( + UINT8 CsId + ) +{ + UINT32 Reg, SpiRegBase = PcdGet32 (PcdSpiRegBase); + + Reg = MmioRead32 (SpiRegBase + SPI_CTRL_REG); + Reg &= ~SPI_CS_NUM_MASK; + Reg |= (CsId << SPI_CS_NUM_OFFSET); + MmioWrite32 (SpiRegBase + SPI_CTRL_REG, Reg); +} + +STATIC +VOID +SpiActivateCs ( + UINT8 IN CsId + ) +{ + UINT32 Reg, SpiRegBase = PcdGet32 (PcdSpiRegBase); + + SpiSetCs(CsId); + Reg = MmioRead32 (SpiRegBase + SPI_CTRL_REG); + Reg |= SPI_CS_EN_MASK; + MmioWrite32(SpiRegBase + SPI_CTRL_REG, Reg); +} + +STATIC +VOID +SpiDeactivateCs ( + VOID + ) +{ + UINT32 Reg, SpiRegBase = PcdGet32 (PcdSpiRegBase); + + Reg = MmioRead32 (SpiRegBase + SPI_CTRL_REG); + Reg &= ~SPI_CS_EN_MASK; + MmioWrite32(SpiRegBase + SPI_CTRL_REG, Reg); +} + +STATIC +VOID +SpiSetupTransfer ( + IN MARVELL_SPI_MASTER_PROTOCOL *This, + IN SPI_DEVICE *Slave + ) +{ + SPI_MASTER *SpiMaster; + UINT32 Reg, SpiRegBase, CoreClock, SpiMaxFreq; + + SpiMaster = SPI_MASTER_FROM_SPI_MASTER_PROTOCOL (This); + + // Initialize values from PCDs + SpiRegBase = PcdGet32 (PcdSpiRegBase); + CoreClock = PcdGet32 (PcdSpiClockFrequency); + SpiMaxFreq = PcdGet32 (PcdSpiMaxFrequency); + + EfiAcquireLock (&SpiMaster->Lock); + + Reg = MmioRead32 (SpiRegBase + SPI_CONF_REG); + Reg |= SPI_BYTE_LENGTH; + MmioWrite32 (SpiRegBase + SPI_CONF_REG, Reg); + + SpiSetCs(Slave->Cs); + + SpiSetBaudRate (CoreClock, SpiMaxFreq); + + Reg = MmioRead32 (SpiRegBase + SPI_CONF_REG); + Reg &= ~(SPI_CPOL_MASK | SPI_CPHA_MASK | SPI_TXLSBF_MASK | SPI_RXLSBF_MASK); + + switch (Slave->Mode) { + case SPI_MODE0: + break; + case SPI_MODE1: + Reg |= SPI_CPHA_MASK; + break; + case SPI_MODE2: + Reg |= SPI_CPOL_MASK; + break; + case SPI_MODE3: + Reg |= SPI_CPOL_MASK; + Reg |= SPI_CPHA_MASK; + break; + } + + MmioWrite32 (SpiRegBase + SPI_CONF_REG, Reg); + + EfiReleaseLock (&SpiMaster->Lock); +} + +EFI_STATUS +EFIAPI +MvSpiTransfer ( + IN MARVELL_SPI_MASTER_PROTOCOL *This, + IN SPI_DEVICE *Slave, + IN UINTN DataByteCount, + IN VOID *DataOut, + IN VOID *DataIn, + IN UINTN Flag + ) +{ + SPI_MASTER *SpiMaster; + UINT64 Length; + UINT32 Iterator, Reg, SpiRegBase; + UINT8 *DataOutPtr = (UINT8 *)DataOut; + UINT8 *DataInPtr = (UINT8 *)DataIn; + UINT8 DataToSend = 0; + + SpiMaster = SPI_MASTER_FROM_SPI_MASTER_PROTOCOL (This); + + SpiRegBase = PcdGet32 (PcdSpiRegBase); + + Length = 8 * DataByteCount; + + EfiAcquireLock (&SpiMaster->Lock); + + if (Flag & SPI_TRANSFER_BEGIN) { + SpiActivateCs (Slave->Cs); + } + + // Set 8-bit mode + Reg = MmioRead32 (SpiRegBase + SPI_CONF_REG); + Reg &= ~SPI_BYTE_LENGTH; + MmioWrite32 (SpiRegBase + SPI_CONF_REG, Reg); + + while (Length > 0) { + if (DataOut != NULL) { + DataToSend = *DataOutPtr & 0xFF; + } + // Transmit Data + MmioWrite32 (SpiRegBase + SPI_INT_CAUSE_REG, 0x0); + MmioWrite32 (SpiRegBase + SPI_DATA_OUT_REG, DataToSend); + // Wait for memory ready + for (Iterator = 0; Iterator < SPI_TIMEOUT; Iterator++) { + if (MmioRead32 (SpiRegBase + SPI_INT_CAUSE_REG)) { + *DataInPtr = MmioRead32 (SpiRegBase + SPI_DATA_IN_REG); + + if (DataInPtr != NULL) { + DataInPtr++; + } + if (DataOutPtr != NULL) { + DataOutPtr++; + } + Length -= 8; + break; + } + } + + if (Iterator >= SPI_TIMEOUT) { + DEBUG ((DEBUG_ERROR, "Timeout\n")); + } + } + + if (Flag & SPI_TRANSFER_END) { + SpiDeactivateCs (); + } + + EfiReleaseLock (&SpiMaster->Lock); + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +MvSpiReadWrite ( + IN MARVELL_SPI_MASTER_PROTOCOL *This, + IN SPI_DEVICE *Slave, + IN UINT8 *Cmd, + IN UINTN CmdSize, + IN UINT8 *DataOut, + OUT UINT8 *DataIn, + IN UINTN DataSize + ) +{ + EFI_STATUS Status; + + Status = MvSpiTransfer (This, Slave, CmdSize, Cmd, NULL, SPI_TRANSFER_BEGIN); + if (EFI_ERROR (Status)) { + Print (L"Spi Transfer Error\n"); + return EFI_DEVICE_ERROR; + } + + Status = MvSpiTransfer (This, Slave, DataSize, DataOut, DataIn, SPI_TRANSFER_END); + if (EFI_ERROR (Status)) { + Print (L"Spi Transfer Error\n"); + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +MvSpiInit ( + IN MARVELL_SPI_MASTER_PROTOCOL * This + ) +{ + + return EFI_SUCCESS; +} + +SPI_DEVICE * +EFIAPI +MvSpiSetupSlave ( + IN MARVELL_SPI_MASTER_PROTOCOL *This, + IN UINTN Cs, + IN SPI_MODE Mode + ) +{ + SPI_DEVICE *Slave; + + Slave = AllocateZeroPool (sizeof(SPI_DEVICE)); + if (Slave == NULL) { + DEBUG((DEBUG_ERROR, "Cannot allocate memory\n")); + return NULL; + } + + Slave->Cs = Cs; + Slave->Mode = Mode; + + SpiSetupTransfer (This, Slave); + + return Slave; +} + +EFI_STATUS +EFIAPI +MvSpiFreeSlave ( + IN SPI_DEVICE *Slave + ) +{ + FreePool (Slave); + + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +SpiMasterInitProtocol ( + IN MARVELL_SPI_MASTER_PROTOCOL *SpiMasterProtocol + ) +{ + + SpiMasterProtocol->Init = MvSpiInit; + SpiMasterProtocol->SetupDevice = MvSpiSetupSlave; + SpiMasterProtocol->FreeDevice = MvSpiFreeSlave; + SpiMasterProtocol->Transfer = MvSpiTransfer; + SpiMasterProtocol->ReadWrite = MvSpiReadWrite; + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +SpiMasterEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + mSpiMasterInstance = AllocateZeroPool (sizeof (SPI_MASTER)); + + if (mSpiMasterInstance == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + EfiInitializeLock (&mSpiMasterInstance->Lock, TPL_NOTIFY); + + SpiMasterInitProtocol (&mSpiMasterInstance->SpiMasterProtocol); + + mSpiMasterInstance->Signature = SPI_MASTER_SIGNATURE; + + Status = gBS->InstallMultipleProtocolInterfaces ( + &(mSpiMasterInstance->Handle), + &gMarvellSpiMasterProtocolGuid, + &(mSpiMasterInstance->SpiMasterProtocol), + NULL + ); + if (EFI_ERROR (Status)) { + FreePool (mSpiMasterInstance); + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} diff --git a/Drivers/Spi/MvSpiDxe.h b/Drivers/Spi/MvSpiDxe.h new file mode 100644 index 0000000..1401f62 --- /dev/null +++ b/Drivers/Spi/MvSpiDxe.h @@ -0,0 +1,145 @@ +/******************************************************************************* +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. + +*******************************************************************************/ +#ifndef __SPI_MASTER_H__ +#define __SPI_MASTER_H__ + +#include <Library/IoLib.h> +#include <Library/PcdLib.h> +#include <Library/UefiLib.h> +#include <Library/DebugLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Uefi/UefiBaseType.h> +#include <Library/BaseMemoryLib.h> +#include <Library/UefiBootServicesTableLib.h> + +#include <Protocol/Spi.h> + +#define SPI_MASTER_SIGNATURE SIGNATURE_32 ('M', 'S', 'P', 'I') +#define SPI_MASTER_FROM_SPI_MASTER_PROTOCOL(a) CR (a, SPI_MASTER, SpiMasterProtocol, SPI_MASTER_SIGNATURE) + +// Marvell Flash Device Controller Registers +#define SPI_CTRL_REG (0x00) +#define SPI_CONF_REG (0x04) +#define SPI_DATA_OUT_REG (0x08) +#define SPI_DATA_IN_REG (0x0c) +#define SPI_INT_CAUSE_REG (0x10) + +// Serial Memory Interface Control Register Masks +#define SPI_CS_NUM_OFFSET 2 +#define SPI_CS_NUM_MASK (0x7 << SPI_CS_NUM_OFFSET) +#define SPI_MEM_READY_MASK (0x1 << 1) +#define SPI_CS_EN_MASK (0x1 << 0) + +// Serial Memory Interface Configuration Register Masks +#define SPI_BYTE_LENGTH_OFFSET 5 +#define SPI_BYTE_LENGTH (0x1 << SPI_BYTE_LENGTH_OFFSET) +#define SPI_CPOL_OFFSET 11 +#define SPI_CPOL_MASK (0x1 << SPI_CPOL_OFFSET) +#define SPI_CPHA_OFFSET 12 +#define SPI_CPHA_MASK (0x1 << SPI_CPHA_OFFSET) +#define SPI_TXLSBF_OFFSET 13 +#define SPI_TXLSBF_MASK (0x1 << SPI_TXLSBF_OFFSET) +#define SPI_RXLSBF_OFFSET 14 +#define SPI_RXLSBF_MASK (0x1 << SPI_RXLSBF_OFFSET) + +#define SPI_SPR_OFFSET 0 +#define SPI_SPR_MASK (0xf << SPI_SPR_OFFSET) +#define SPI_SPPR_0_OFFSET 4 +#define SPI_SPPR_0_MASK (0x1 << SPI_SPPR_0_OFFSET) +#define SPI_SPPR_HI_OFFSET 6 +#define SPI_SPPR_HI_MASK (0x3 << SPI_SPPR_HI_OFFSET) + +#define SPI_TRANSFER_BEGIN 0x01 // Assert CS before transfer +#define SPI_TRANSFER_END 0x02 // Deassert CS after transfers + +#define SPI_TIMEOUT 100000 + +typedef struct { + MARVELL_SPI_MASTER_PROTOCOL SpiMasterProtocol; + UINTN Signature; + EFI_HANDLE Handle; + EFI_LOCK Lock; +} SPI_MASTER; + +EFI_STATUS +EFIAPI +MvSpiTransfer ( + IN MARVELL_SPI_MASTER_PROTOCOL *This, + IN SPI_DEVICE *Slave, + IN UINTN DataByteCount, + IN VOID *DataOut, + IN VOID *DataIn, + IN UINTN Flag + ); + +EFI_STATUS +EFIAPI +MvSpiReadWrite ( + IN MARVELL_SPI_MASTER_PROTOCOL *This, + IN SPI_DEVICE *Slave, + IN UINT8 *Cmd, + IN UINTN CmdSize, + IN UINT8 *DataOut, + OUT UINT8 *DataIn, + IN UINTN DataSize + ); + +EFI_STATUS +EFIAPI +MvSpiInit ( + IN MARVELL_SPI_MASTER_PROTOCOL * This + ); + +SPI_DEVICE * +EFIAPI +MvSpiSetupSlave ( + IN MARVELL_SPI_MASTER_PROTOCOL * This, + IN UINTN Cs, + IN SPI_MODE Mode + ); + +EFI_STATUS +EFIAPI +MvSpiFreeSlave ( + IN SPI_DEVICE *Slave + ); + +EFI_STATUS +EFIAPI +SpiMasterEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +#endif // __SPI_MASTER_H__ diff --git a/Drivers/Spi/MvSpiDxe.inf b/Drivers/Spi/MvSpiDxe.inf new file mode 100644 index 0000000..1dd3029 --- /dev/null +++ b/Drivers/Spi/MvSpiDxe.inf @@ -0,0 +1,66 @@ +# +# 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 = 0x00010005 + BASE_NAME = SpiMasterDxe + FILE_GUID = c19dbc8a-f4f9-43b0-aee5-802e3ed03d15 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = SpiMasterEntryPoint + +[Sources] + MvSpiDxe.c + MvSpiDxe.h + +[Packages] + MdePkg/MdePkg.dec + OpenPlatformPkg/Platforms/Marvell/Marvell.dec + +[LibraryClasses] + UefiBootServicesTableLib + UefiDriverEntryPoint + TimerLib + UefiLib + DebugLib + MemoryAllocationLib + IoLib + +[FixedPcd] + gMarvellTokenSpaceGuid.PcdSpiRegBase + gMarvellTokenSpaceGuid.PcdSpiClockFrequency + gMarvellTokenSpaceGuid.PcdSpiMaxFrequency + +[Protocols] + gMarvellSpiMasterProtocolGuid + +[Depex] + TRUE diff --git a/Platforms/Marvell/Marvell.dec b/Platforms/Marvell/Marvell.dec index dc670e7..e76678e 100644 --- a/Platforms/Marvell/Marvell.dec +++ b/Platforms/Marvell/Marvell.dec @@ -116,6 +116,11 @@ gMarvellTokenSpaceGuid.PcdI2cBaudRate|0|UINT32|0x3000049 gMarvellTokenSpaceGuid.PcdI2cBusCount|0|UINT32|0x3000183
+#SPI + gMarvellTokenSpaceGuid.PcdSpiRegBase|0|UINT32|0x3000051 + gMarvellTokenSpaceGuid.PcdSpiMaxFrequency|0|UINT32|0x30000052 + gMarvellTokenSpaceGuid.PcdSpiClockFrequency|0|UINT32|0x30000053 + [Protocols] gMarvellEepromProtocolGuid = { 0xcd728a1f, 0x45b5, 0x4feb, { 0x98, 0xc8, 0x31, 0x3d, 0xa8, 0x11, 0x74, 0x62 }} gMarvellSpiMasterProtocolGuid = { 0x23de66a3, 0xf666, 0x4b3e, { 0xaa, 0xa2, 0x68, 0x9b, 0x18, 0xae, 0x2e, 0x19 }}
From: Jan Dąbroś jsd@semihalf.com
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 --- Platforms/Marvell/Armada/Armada.dsc.inc | 1 + Platforms/Marvell/Armada/Armada70x0.dsc | 5 +++++ Platforms/Marvell/Armada/Armada70x0.fdf | 1 + 3 files changed, 7 insertions(+)
diff --git a/Platforms/Marvell/Armada/Armada.dsc.inc b/Platforms/Marvell/Armada/Armada.dsc.inc index b5b5744..a5b9a12 100644 --- a/Platforms/Marvell/Armada/Armada.dsc.inc +++ b/Platforms/Marvell/Armada/Armada.dsc.inc @@ -385,6 +385,7 @@ OpenPlatformPkg/Drivers/I2c/MvI2cDxe/MvI2cDxe.inf MdeModulePkg/Bus/I2c/I2cDxe/I2cDxe.inf OpenPlatformPkg/Drivers/I2c/Devices/MvEeprom/MvEeprom.inf + OpenPlatformPkg/Drivers/Spi/MvSpiDxe.inf
MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf diff --git a/Platforms/Marvell/Armada/Armada70x0.dsc b/Platforms/Marvell/Armada/Armada70x0.dsc index 76b06e0..291532f 100644 --- a/Platforms/Marvell/Armada/Armada70x0.dsc +++ b/Platforms/Marvell/Armada/Armada70x0.dsc @@ -84,3 +84,8 @@ gMarvellTokenSpaceGuid.PcdI2cClockFrequency|250000000 gMarvellTokenSpaceGuid.PcdI2cBaudRate|100000 gMarvellTokenSpaceGuid.PcdI2cBusCount|2 + + #SPI + gMarvellTokenSpaceGuid.PcdSpiRegBase|0xF2700680 + gMarvellTokenSpaceGuid.PcdSpiMaxFrequency|10000000 + gMarvellTokenSpaceGuid.PcdSpiClockFrequency|200000000 diff --git a/Platforms/Marvell/Armada/Armada70x0.fdf b/Platforms/Marvell/Armada/Armada70x0.fdf index 552cb35..d63b361 100644 --- a/Platforms/Marvell/Armada/Armada70x0.fdf +++ b/Platforms/Marvell/Armada/Armada70x0.fdf @@ -105,6 +105,7 @@ FvNameGuid = 5eda4200-2c5f-43cb-9da3-0baf74b1b30c INF OpenPlatformPkg/Drivers/I2c/MvI2cDxe/MvI2cDxe.inf INF MdeModulePkg/Bus/I2c/I2cDxe/I2cDxe.inf INF OpenPlatformPkg/Drivers/I2c/Devices/MvEeprom/MvEeprom.inf + INF OpenPlatformPkg/Drivers/Spi/MvSpiDxe.inf
# Multiple Console IO support INF MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
From: Jan Dąbroś jsd@semihalf.com
Add MARVELL_SPI_FLASH_PROTOCOL and register containg folder in Marvell/Marvell.dec in order to make it public. This protocol contains functions used to manage 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 --- Platforms/Marvell/Include/Protocol/SpiFlash.h | 113 ++++++++++++++++++++++++++ Platforms/Marvell/Marvell.dec | 1 + 2 files changed, 114 insertions(+) create mode 100644 Platforms/Marvell/Include/Protocol/SpiFlash.h
diff --git a/Platforms/Marvell/Include/Protocol/SpiFlash.h b/Platforms/Marvell/Include/Protocol/SpiFlash.h new file mode 100644 index 0000000..743bb87 --- /dev/null +++ b/Platforms/Marvell/Include/Protocol/SpiFlash.h @@ -0,0 +1,113 @@ +/******************************************************************************* +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. + +*******************************************************************************/ +#ifndef __MV_SPI_FLASH__ +#define __MV_SPI_FLASH__ + +#include <Protocol/Spi.h> + +#define CMD_READ_ID 0x9f +#define READ_STATUS_REG_CMD 0x0b +#define CMD_WRITE_ENABLE 0x06 +#define CMD_FLAG_STATUS 0x70 +#define CMD_WRITE_STATUS_REG 0x01 +#define CMD_READ_ARRAY_FAST 0x0b +#define CMD_PAGE_PROGRAM 0x02 +#define CMD_BANK_WRITE 0xc5 +#define CMD_ERASE_64K 0xd8 +#define CMD_4B_ADDR_ENABLE 0xb7 + +extern EFI_GUID gMarvellSpiFlashProtocolGuid; + +typedef struct _MARVELL_SPI_FLASH_PROTOCOL MARVELL_SPI_FLASH_PROTOCOL; + +typedef +EFI_STATUS +(EFIAPI *MV_SPI_FLASH_INIT) ( + IN MARVELL_SPI_FLASH_PROTOCOL *This, + IN SPI_DEVICE *SpiDev + ); + +typedef +EFI_STATUS +(EFIAPI *MV_SPI_FLASH_READ_ID) ( + IN SPI_DEVICE *SpiDev, + IN UINT32 DataByteCount, + IN OUT UINT8 *Buffer + ); + +typedef +EFI_STATUS +(EFIAPI *MV_SPI_FLASH_READ) ( + IN SPI_DEVICE *SpiDev, + IN UINT32 Address, + IN UINTN DataByteCount, + IN VOID *Buffer + ); + +typedef +EFI_STATUS +(EFIAPI *MV_SPI_FLASH_WRITE) ( + IN SPI_DEVICE *SpiDev, + IN UINT32 Address, + IN UINTN DataByteCount, + IN VOID *Buffer + ); + +typedef +EFI_STATUS +(EFIAPI *MV_SPI_FLASH_ERASE) ( + IN SPI_DEVICE *SpiDev, + IN UINTN Address, + IN UINTN DataByteCount + ); + +typedef +EFI_STATUS +(EFIAPI *MV_SPI_FLASH_UPDATE) ( + IN SPI_DEVICE *SpiDev, + IN UINT32 Address, + IN UINTN DataByteCount, + IN UINT8 *Buffer + ); + +struct _MARVELL_SPI_FLASH_PROTOCOL { + MV_SPI_FLASH_INIT Init; + MV_SPI_FLASH_READ_ID ReadId; + MV_SPI_FLASH_READ Read; + MV_SPI_FLASH_WRITE Write; + MV_SPI_FLASH_ERASE Erase; + MV_SPI_FLASH_UPDATE Update; +}; + +#endif // __MV_SPI_FLASH__ diff --git a/Platforms/Marvell/Marvell.dec b/Platforms/Marvell/Marvell.dec index e76678e..7dd3e07 100644 --- a/Platforms/Marvell/Marvell.dec +++ b/Platforms/Marvell/Marvell.dec @@ -124,4 +124,5 @@ [Protocols] gMarvellEepromProtocolGuid = { 0xcd728a1f, 0x45b5, 0x4feb, { 0x98, 0xc8, 0x31, 0x3d, 0xa8, 0x11, 0x74, 0x62 }} gMarvellSpiMasterProtocolGuid = { 0x23de66a3, 0xf666, 0x4b3e, { 0xaa, 0xa2, 0x68, 0x9b, 0x18, 0xae, 0x2e, 0x19 }} + gMarvellSpiFlashProtocolGuid = { 0x9accb423, 0x5bd2, 0x4fca, { 0x9b, 0x4c, 0x2e, 0x65, 0xfc, 0x25, 0xdf, 0x21 }}
From: Jan Dąbroś jsd@semihalf.com
This patch add driver for managing Spi flash It consumes MARVELL_SPI_FLASH_PROTOCOL and enables configuration by PCD entries.
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 --- Documentation/Marvell/PortingGuide/SpiFlash.txt | 23 + Drivers/Spi/Devices/MvSpiFlash.c | 531 ++++++++++++++++++++++++ Drivers/Spi/Devices/MvSpiFlash.h | 132 ++++++ Drivers/Spi/Devices/MvSpiFlash.inf | 67 +++ Platforms/Marvell/Marvell.dec | 6 + 5 files changed, 759 insertions(+) create mode 100644 Documentation/Marvell/PortingGuide/SpiFlash.txt create mode 100755 Drivers/Spi/Devices/MvSpiFlash.c create mode 100755 Drivers/Spi/Devices/MvSpiFlash.h create mode 100644 Drivers/Spi/Devices/MvSpiFlash.inf
diff --git a/Documentation/Marvell/PortingGuide/SpiFlash.txt b/Documentation/Marvell/PortingGuide/SpiFlash.txt new file mode 100644 index 0000000..226db40 --- /dev/null +++ b/Documentation/Marvell/PortingGuide/SpiFlash.txt @@ -0,0 +1,23 @@ +SpiFlash driver configuration +----------------------------- +Folowing PCDs for spi flash driver configuration must be set properly: + + gMarvellTokenSpaceGuid.PcdSpiFlashAddressCycles + +Size of SPI flash address in bytes (3 or 4) + + gMarvellTokenSpaceGuid.PcdSpiFlashEraseSize + +Size of minimal erase block in bytes + + gMarvellTokenSpaceGuid.PcdSpiFlashPageSize + +Size of SPI flash page + + gMarvellTokenSpaceGuid.PcdSpiFlashId + +Id of SPI flash + + gMarvellTokenSpaceGuid.PcdSpiFlashPollCmd + +Spi flash polling flag diff --git a/Drivers/Spi/Devices/MvSpiFlash.c b/Drivers/Spi/Devices/MvSpiFlash.c new file mode 100755 index 0000000..9a04493 --- /dev/null +++ b/Drivers/Spi/Devices/MvSpiFlash.c @@ -0,0 +1,531 @@ +/******************************************************************************* +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 "MvSpiFlash.h" + +MARVELL_SPI_MASTER_PROTOCOL *SpiMasterProtocol; +SPI_FLASH_INSTANCE *mSpiFlashInstance; + +STATIC +VOID +SpiFlashFormatAddress ( + IN UINT32 Address, + IN UINT8 AddrSize, + IN OUT UINT8 *Cmd + ) +{ + if (AddrSize == 4) { + Cmd[1] = Address >> 24; + Cmd[2] = Address >> 16; + Cmd[3] = Address >> 8; + Cmd[4] = Address; + } else { + Cmd[1] = Address >> 16; + Cmd[2] = Address >> 8; + Cmd[3] = Address; + } +} + +STATIC +EFI_STATUS +MvSpiFlashReadCmd ( + IN SPI_DEVICE *Slave, + IN UINT8 *Cmd, + IN UINTN CmdSize, + OUT UINT8 *DataIn, + IN UINTN DataSize + ) +{ + EFI_STATUS Status; + + // Send command and gather response + Status = SpiMasterProtocol->ReadWrite (SpiMasterProtocol, Slave, Cmd, + CmdSize, NULL, DataIn, DataSize); + + return Status; +} + +STATIC +EFI_STATUS +MvSpiFlashWriteEnableCmd ( + IN SPI_DEVICE *Slave + ) +{ + EFI_STATUS Status; + UINT8 CmdEn = CMD_WRITE_ENABLE; + + // Send write_enable command + Status = SpiMasterProtocol->Transfer (SpiMasterProtocol, Slave, 1, + &CmdEn, NULL, SPI_TRANSFER_BEGIN | SPI_TRANSFER_END); + + return Status; +} + +STATIC +EFI_STATUS +MvSpiFlashWriteCommon ( + IN SPI_DEVICE *Slave, + IN UINT8 *Cmd, + IN UINT32 Length, + IN UINT8* Buffer, + IN UINT32 BufferLength + ) +{ + UINT8 CmdStatus = CMD_READ_STATUS; + UINT8 State; + UINT32 Counter = 0xFFFFF; + UINT8 poll_bit = STATUS_REG_POLL_WIP; + UINT8 check_status = 0x0; + + CmdStatus = (UINT8)PcdGet32 (PcdSpiFlashPollCmd); + if (CmdStatus == CMD_FLAG_STATUS) { + poll_bit = STATUS_REG_POLL_PEC; + check_status = poll_bit; + } + + // Send command + MvSpiFlashWriteEnableCmd (Slave); + + // Write data + SpiMasterProtocol->ReadWrite (SpiMasterProtocol, Slave, Cmd, Length, + Buffer, NULL, BufferLength); + + // Poll status register + SpiMasterProtocol->Transfer (SpiMasterProtocol, Slave, 1, &CmdStatus, + NULL, SPI_TRANSFER_BEGIN); + do { + SpiMasterProtocol->Transfer (SpiMasterProtocol, Slave, 1, NULL, &State, + 0); + Counter--; + if ((State & poll_bit) == check_status) + break; + } while (Counter > 0); + if (Counter == 0) { + DEBUG((DEBUG_ERROR, "SpiFlash: Timeout while writing to spi flash\n")); + return EFI_DEVICE_ERROR; + } + + // Deactivate CS + SpiMasterProtocol->Transfer (SpiMasterProtocol, Slave, 0, NULL, NULL, SPI_TRANSFER_END); + + return EFI_SUCCESS; +} + +STATIC +VOID +SpiFlashCmdBankaddrWrite ( + IN SPI_DEVICE *Slave, + IN UINT8 BankSel + ) +{ + UINT8 Cmd = CMD_BANK_WRITE; + + MvSpiFlashWriteCommon (Slave, &Cmd, 1, &BankSel, 1); +} + +STATIC +UINT8 +SpiFlashBank ( + IN SPI_DEVICE *Slave, + IN UINT32 Offset + ) +{ + UINT8 BankSel; + + BankSel = Offset / SPI_FLASH_16MB_BOUN; + + SpiFlashCmdBankaddrWrite (Slave, BankSel); + + return BankSel; +} + +EFI_STATUS +MvSpiFlashErase ( + IN SPI_DEVICE *Slave, + IN UINTN Offset, + IN UINTN Length + ) +{ + EFI_STATUS Status; + UINT32 AddrSize, EraseAddr; + UINTN EraseSize; + UINT8 Cmd[5]; + + AddrSize = PcdGet32 (PcdSpiFlashAddressCycles); + EraseSize = PcdGet64 (PcdSpiFlashEraseSize); + + // Check input parameters + if (Offset % EraseSize || Length % EraseSize) { + DEBUG((DEBUG_ERROR, "SpiFlash: Either erase offset or length " + "is not multiple of erase size\n")); + return EFI_DEVICE_ERROR; + } + + Cmd[0] = CMD_ERASE_64K; + while (Length) { + EraseAddr = Offset; + + SpiFlashBank (Slave, EraseAddr); + + SpiFlashFormatAddress (EraseAddr, AddrSize, Cmd); + + // Programm proper erase address + Status = MvSpiFlashWriteCommon (Slave, Cmd, AddrSize + 1, NULL, 0); + if (EFI_ERROR (Status)) { + DEBUG((DEBUG_ERROR, "SpiFlash: Error while programming target address\n")); + return Status; + } + + Offset += EraseSize; + Length -= EraseSize; + } + return EFI_SUCCESS; +} + +EFI_STATUS +MvSpiFlashRead ( + IN SPI_DEVICE *Slave, + IN UINT32 Offset, + IN UINTN Length, + IN VOID *Buf + ) +{ + EFI_STATUS Status = EFI_SUCCESS; + UINT8 Cmd[6]; + UINT32 AddrSize, ReadAddr, ReadLength, RemainLength; + UINTN BankSel = 0; + + AddrSize = PcdGet32 (PcdSpiFlashAddressCycles); + + Cmd[0] = CMD_READ_ARRAY_FAST; + + // Sign end of address with 0 byte + Cmd[5] = 0; + + while (Length) { + ReadAddr = Offset; + + BankSel = SpiFlashBank (Slave, ReadAddr); + + RemainLength = (SPI_FLASH_16MB_BOUN * (BankSel + 1)) - Offset; + if (Length < RemainLength) { + ReadLength = Length; + } else { + ReadLength = RemainLength; + } + SpiFlashFormatAddress (ReadAddr, AddrSize, Cmd); + // Program proper read address and read data + Status = MvSpiFlashReadCmd (Slave, Cmd, AddrSize + 2, Buf, Length); + + Offset += ReadLength; + Length -= ReadLength; + Buf += ReadLength; + } + + return Status; +} + +EFI_STATUS +MvSpiFlashWrite ( + IN SPI_DEVICE *Slave, + IN UINT32 Offset, + IN UINTN Length, + IN VOID *Buf + ) +{ + EFI_STATUS Status; + UINTN ByteAddr, ChunkLength, ActualIndex, PageSize; + UINT32 WriteAddr; + UINT8 Cmd[5], AddrSize; + + AddrSize = PcdGet32 (PcdSpiFlashAddressCycles); + PageSize = PcdGet32 (PcdSpiFlashPageSize); + + Cmd[0] = CMD_PAGE_PROGRAM; + + for (ActualIndex = 0; ActualIndex < Length; ActualIndex += ChunkLength) { + WriteAddr = Offset; + + SpiFlashBank (Slave, WriteAddr); + + ByteAddr = Offset % PageSize; + + ChunkLength = MIN(Length - ActualIndex, (UINT64) (PageSize - ByteAddr)); + + SpiFlashFormatAddress (WriteAddr, AddrSize, Cmd); + + // Program proper write address and write data + Status = MvSpiFlashWriteCommon (Slave, Cmd, AddrSize + 1, Buf + ActualIndex, + ChunkLength); + if (EFI_ERROR (Status)) { + DEBUG((DEBUG_ERROR, "SpiFlash: Error while programming write address\n")); + return Status; + } + + Offset += ChunkLength; + } + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +MvSpiFlashUpdateBlock ( + IN SPI_DEVICE *Slave, + IN UINT32 Offset, + IN UINTN ToUpdate, + IN UINT8 *Buf, + IN UINT8 *TmpBuf, + IN UINTN EraseSize + ) +{ + EFI_STATUS Status; + + // Read backup + Status = MvSpiFlashRead (Slave, Offset, EraseSize, TmpBuf); + if (EFI_ERROR (Status)) { + DEBUG((DEBUG_ERROR, "SpiFlash: Update: Error while reading old data\n")); + return Status; + } + + // Erase entire sector + Status = MvSpiFlashErase (Slave, Offset, EraseSize); + if (EFI_ERROR (Status)) { + DEBUG((DEBUG_ERROR, "SpiFlash: Update: Error while erasing block\n")); + return Status; + } + + // Write new data + MvSpiFlashWrite (Slave, Offset, ToUpdate, Buf); + if (EFI_ERROR (Status)) { + DEBUG((DEBUG_ERROR, "SpiFlash: Update: Error while writing new data\n")); + return Status; + } + + // Write backup + if (ToUpdate != EraseSize) { + Status = MvSpiFlashWrite (Slave, Offset + ToUpdate, EraseSize - ToUpdate, + &TmpBuf[ToUpdate]); + if (EFI_ERROR (Status)) { + DEBUG((DEBUG_ERROR, "SpiFlash: Update: Error while writing backup\n")); + return Status; + } + } + + return EFI_SUCCESS; +} + +EFI_STATUS +MvSpiFlashUpdate ( + IN SPI_DEVICE *Slave, + IN UINT32 Offset, + IN UINTN ByteCount, + IN UINT8 *Buf + ) +{ + EFI_STATUS Status; + UINT64 EraseSize, ToUpdate, Scale = 1; + UINT8 *TmpBuf, *End; + + EraseSize = PcdGet64 (PcdSpiFlashEraseSize); + + End = Buf + ByteCount; + + TmpBuf = (UINT8 *)AllocateZeroPool (EraseSize); + if (TmpBuf == NULL) { + DEBUG((DEBUG_ERROR, "SpiFlash: Cannot allocate memory\n")); + return EFI_OUT_OF_RESOURCES; + } + + if (End - Buf >= 200) + Scale = (End - Buf) / 100; + + for (; Buf < End; Buf += ToUpdate, Offset += ToUpdate) { + ToUpdate = MIN((UINT64)(End - Buf), EraseSize); + Print (L" \rUpdating, %d%%", 100 - (End - Buf) / Scale); + Status = MvSpiFlashUpdateBlock (Slave, Offset, ToUpdate, Buf, TmpBuf, EraseSize); + + if (EFI_ERROR (Status)) { + DEBUG((DEBUG_ERROR, "SpiFlash: Error while updating\n")); + return Status; + } + } + + Print(L"\n"); + FreePool (TmpBuf); + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +MvSpiFlashReadId ( + IN SPI_DEVICE *SpiDev, + IN UINT32 DataByteCount, + IN OUT UINT8 *Buffer + ) +{ + EFI_STATUS Status; + UINT8 *DataOut; + + DataOut = (UINT8 *) AllocateZeroPool (DataByteCount); + if (DataOut == NULL) { + DEBUG((DEBUG_ERROR, "SpiFlash: Cannot allocate memory\n")); + return EFI_OUT_OF_RESOURCES; + } + Status = SpiMasterProtocol->Transfer (SpiMasterProtocol, SpiDev, + DataByteCount, Buffer, DataOut, SPI_TRANSFER_BEGIN | SPI_TRANSFER_END); + if (EFI_ERROR(Status)) { + FreePool (DataOut); + DEBUG((DEBUG_ERROR, "SpiFlash: Spi transfer error\n")); + return Status; + } + + // Bytes 1,2 and 3 contain SPI flash ID + Buffer[0] = DataOut[1]; + Buffer[1] = DataOut[2]; + Buffer[2] = DataOut[3]; + + FreePool (DataOut); + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +MvSpiFlashInit ( + IN MARVELL_SPI_FLASH_PROTOCOL *This, + IN SPI_DEVICE *Slave + ) +{ + EFI_STATUS Status; + UINT8 Cmd, StatusRegister; + UINT32 AddrSize; + + AddrSize = PcdGet32 (PcdSpiFlashAddressCycles); + + if (AddrSize == 4) { + // Set 4 byte address mode + Status = MvSpiFlashWriteEnableCmd (Slave); + if (EFI_ERROR (Status)) { + DEBUG((DEBUG_ERROR, "SpiFlash: Error while setting write_enable\n")); + return Status; + } + + Cmd = CMD_4B_ADDR_ENABLE; + Status = SpiMasterProtocol->Transfer (SpiMasterProtocol, Slave, 1, &Cmd, NULL, + SPI_TRANSFER_BEGIN | SPI_TRANSFER_END); + if (EFI_ERROR (Status)) { + DEBUG((DEBUG_ERROR, "SpiFlash: Error while setting 4B address\n")); + return Status; + } + } + + // Write flash status register + Status = MvSpiFlashWriteEnableCmd (Slave); + if (EFI_ERROR (Status)) { + DEBUG((DEBUG_ERROR, "SpiFlash: Error while setting write_enable\n")); + return Status; + } + + Cmd = CMD_WRITE_STATUS_REG; + StatusRegister = 0x0; + Status = SpiMasterProtocol->ReadWrite (SpiMasterProtocol, Slave, &Cmd, 1, + &StatusRegister, NULL, 1); + if (EFI_ERROR (Status)) { + DEBUG((DEBUG_ERROR, "SpiFlash: Error with spi transfer\n")); + return Status; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +MvSpiFlashInitProtocol ( + IN MARVELL_SPI_FLASH_PROTOCOL *SpiFlashProtocol + ) +{ + + SpiFlashProtocol->Init = MvSpiFlashInit; + SpiFlashProtocol->ReadId = MvSpiFlashReadId; + SpiFlashProtocol->Read = MvSpiFlashRead; + SpiFlashProtocol->Write = MvSpiFlashWrite; + SpiFlashProtocol->Erase = MvSpiFlashErase; + SpiFlashProtocol->Update = MvSpiFlashUpdate; + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +MvSpiFlashEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + Status = gBS->LocateProtocol ( + &gMarvellSpiMasterProtocolGuid, + NULL, + (VOID **)&SpiMasterProtocol + ); + if (EFI_ERROR (Status)) { + DEBUG((DEBUG_ERROR, "SpiFlash: Cannot locate SPI Master protocol\n")); + return EFI_DEVICE_ERROR; + } + + mSpiFlashInstance = AllocateZeroPool (sizeof (SPI_FLASH_INSTANCE)); + + if (mSpiFlashInstance == NULL) { + DEBUG((DEBUG_ERROR, "SpiFlash: Cannot allocate memory\n")); + return EFI_OUT_OF_RESOURCES; + } + + MvSpiFlashInitProtocol (&mSpiFlashInstance->SpiFlashProtocol); + + mSpiFlashInstance->Signature = SPI_FLASH_SIGNATURE; + + Status = gBS->InstallMultipleProtocolInterfaces ( + &(mSpiFlashInstance->Handle), + &gMarvellSpiFlashProtocolGuid, + &(mSpiFlashInstance->SpiFlashProtocol), + NULL + ); + if (EFI_ERROR (Status)) { + FreePool (mSpiFlashInstance); + DEBUG((DEBUG_ERROR, "SpiFlash: Cannot install SPI flash protocol\n")); + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} diff --git a/Drivers/Spi/Devices/MvSpiFlash.h b/Drivers/Spi/Devices/MvSpiFlash.h new file mode 100755 index 0000000..3889643 --- /dev/null +++ b/Drivers/Spi/Devices/MvSpiFlash.h @@ -0,0 +1,132 @@ +/******************************************************************************* +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. + +*******************************************************************************/ +#ifndef __MV_SPI_FLASH_H__ +#define __MV_SPI_FLASH_H__ + +#include <Library/IoLib.h> +#include <Library/PcdLib.h> +#include <Library/UefiLib.h> +#include <Library/DebugLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Uefi/UefiBaseType.h> +#include <Library/BaseMemoryLib.h> +#include <Library/UefiBootServicesTableLib.h> + +#include <Protocol/Spi.h> +#include <Protocol/SpiFlash.h> + +#define SPI_FLASH_SIGNATURE SIGNATURE_32 ('F', 'S', 'P', 'I') + +#define CMD_READ_ID 0x9f +#define READ_STATUS_REG_CMD 0x0b +#define CMD_WRITE_ENABLE 0x06 +#define CMD_READ_STATUS 0x05 +#define CMD_FLAG_STATUS 0x70 +#define CMD_WRITE_STATUS_REG 0x01 +#define CMD_READ_ARRAY_FAST 0x0b +#define CMD_PAGE_PROGRAM 0x02 +#define CMD_BANK_WRITE 0xc5 +#define CMD_ERASE_64K 0xd8 +#define CMD_4B_ADDR_ENABLE 0xb7 + +#define STATUS_REG_POLL_WIP (1 << 0) +#define STATUS_REG_POLL_PEC (1 << 7) + +#define SPI_TRANSFER_BEGIN 0x01 // Assert CS before transfer +#define SPI_TRANSFER_END 0x02 // Deassert CS after transfers + +#define SPI_FLASH_16MB_BOUN 0x1000000 + +typedef enum { + SPI_FLASH_READ_ID, + SPI_FLASH_READ, // Read from SPI flash with address + SPI_FLASH_WRITE, // Write to SPI flash with address + SPI_FLASH_ERASE, + SPI_FLASH_UPDATE, + SPI_COMMAND_MAX +} SPI_COMMAND; + +typedef struct { + MARVELL_SPI_FLASH_PROTOCOL SpiFlashProtocol; + UINTN Signature; + EFI_HANDLE Handle; +} SPI_FLASH_INSTANCE; + +EFI_STATUS +EFIAPI +SpiFlashReadId ( + IN SPI_DEVICE *SpiDev, + IN UINT32 DataByteCount, + IN OUT UINT8 *Buffer + ); + +EFI_STATUS +SpiFlashRead ( + IN SPI_DEVICE *Slave, + IN UINT32 Offset, + IN UINTN Length, + IN VOID *Buf + ); + +EFI_STATUS +SpiFlashWrite ( + IN SPI_DEVICE *Slave, + IN UINT32 Offset, + IN UINTN Length, + IN VOID *Buf + ); + +EFI_STATUS +SpiFlashUpdate ( + IN SPI_DEVICE *Slave, + IN UINT32 Offset, + IN UINTN ByteCount, + IN UINT8 *Buf + ); + +EFI_STATUS +SpiFlashErase ( + IN SPI_DEVICE *SpiDev, + IN UINTN Offset, + IN UINTN Length + ); + +EFI_STATUS +EFIAPI +EfiSpiFlashInit ( + IN MARVELL_SPI_FLASH_PROTOCOL *This, + IN SPI_DEVICE *Slave + ); + +#endif // __MV_SPI_FLASH_H__ diff --git a/Drivers/Spi/Devices/MvSpiFlash.inf b/Drivers/Spi/Devices/MvSpiFlash.inf new file mode 100644 index 0000000..85b1728 --- /dev/null +++ b/Drivers/Spi/Devices/MvSpiFlash.inf @@ -0,0 +1,67 @@ +# +# 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 = 0x00010005 + BASE_NAME = SpiFlashDxe + FILE_GUID = 49d7fb74-306d-42bd-94c8-c0c54b181dd7 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = MvSpiFlashEntryPoint + +[Sources] + MvSpiFlash.c + MvSpiFlash.h + +[Packages] + MdePkg/MdePkg.dec + OpenPlatformPkg/Platforms/Marvell/Marvell.dec + +[LibraryClasses] + UefiBootServicesTableLib + UefiDriverEntryPoint + TimerLib + UefiLib + DebugLib + MemoryAllocationLib + +[FixedPcd] + gMarvellTokenSpaceGuid.PcdSpiFlashAddressCycles + gMarvellTokenSpaceGuid.PcdSpiFlashEraseSize + gMarvellTokenSpaceGuid.PcdSpiFlashPageSize + gMarvellTokenSpaceGuid.PcdSpiFlashPollCmd + +[Protocols] + gMarvellSpiMasterProtocolGuid + gMarvellSpiFlashProtocolGuid + +[Depex] + TRUE diff --git a/Platforms/Marvell/Marvell.dec b/Platforms/Marvell/Marvell.dec index 7dd3e07..a2d1956 100644 --- a/Platforms/Marvell/Marvell.dec +++ b/Platforms/Marvell/Marvell.dec @@ -121,6 +121,12 @@ gMarvellTokenSpaceGuid.PcdSpiMaxFrequency|0|UINT32|0x30000052 gMarvellTokenSpaceGuid.PcdSpiClockFrequency|0|UINT32|0x30000053
+ gMarvellTokenSpaceGuid.PcdSpiFlashPollCmd|0|UINT32|0x3000052 + gMarvellTokenSpaceGuid.PcdSpiFlashAddressCycles|0|UINT32|0x3000053 + gMarvellTokenSpaceGuid.PcdSpiFlashEraseSize|0|UINT64|0x3000054 + gMarvellTokenSpaceGuid.PcdSpiFlashPageSize|0|UINT32|0x3000055 + gMarvellTokenSpaceGuid.PcdSpiFlashId|0|UINT32|0x3000056 + [Protocols] gMarvellEepromProtocolGuid = { 0xcd728a1f, 0x45b5, 0x4feb, { 0x98, 0xc8, 0x31, 0x3d, 0xa8, 0x11, 0x74, 0x62 }} gMarvellSpiMasterProtocolGuid = { 0x23de66a3, 0xf666, 0x4b3e, { 0xaa, 0xa2, 0x68, 0x9b, 0x18, 0xae, 0x2e, 0x19 }}
From: Jan Dąbroś jsd@semihalf.com
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 --- Platforms/Marvell/Armada/Armada.dsc.inc | 1 + Platforms/Marvell/Armada/Armada70x0.dsc | 6 ++++++ Platforms/Marvell/Armada/Armada70x0.fdf | 1 + 3 files changed, 8 insertions(+)
diff --git a/Platforms/Marvell/Armada/Armada.dsc.inc b/Platforms/Marvell/Armada/Armada.dsc.inc index a5b9a12..9b1fc7a 100644 --- a/Platforms/Marvell/Armada/Armada.dsc.inc +++ b/Platforms/Marvell/Armada/Armada.dsc.inc @@ -386,6 +386,7 @@ MdeModulePkg/Bus/I2c/I2cDxe/I2cDxe.inf OpenPlatformPkg/Drivers/I2c/Devices/MvEeprom/MvEeprom.inf OpenPlatformPkg/Drivers/Spi/MvSpiDxe.inf + OpenPlatformPkg/Drivers/Spi/Devices/MvSpiFlash.inf
MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf diff --git a/Platforms/Marvell/Armada/Armada70x0.dsc b/Platforms/Marvell/Armada/Armada70x0.dsc index 291532f..29ddf7a 100644 --- a/Platforms/Marvell/Armada/Armada70x0.dsc +++ b/Platforms/Marvell/Armada/Armada70x0.dsc @@ -89,3 +89,9 @@ gMarvellTokenSpaceGuid.PcdSpiRegBase|0xF2700680 gMarvellTokenSpaceGuid.PcdSpiMaxFrequency|10000000 gMarvellTokenSpaceGuid.PcdSpiClockFrequency|200000000 + + gMarvellTokenSpaceGuid.PcdSpiFlashPollCmd|0x70 + gMarvellTokenSpaceGuid.PcdSpiFlashAddressCycles|3 + gMarvellTokenSpaceGuid.PcdSpiFlashEraseSize|65536 + gMarvellTokenSpaceGuid.PcdSpiFlashPageSize|256 + gMarvellTokenSpaceGuid.PcdSpiFlashId|0x20BA18 diff --git a/Platforms/Marvell/Armada/Armada70x0.fdf b/Platforms/Marvell/Armada/Armada70x0.fdf index d63b361..61793dc 100644 --- a/Platforms/Marvell/Armada/Armada70x0.fdf +++ b/Platforms/Marvell/Armada/Armada70x0.fdf @@ -106,6 +106,7 @@ FvNameGuid = 5eda4200-2c5f-43cb-9da3-0baf74b1b30c INF MdeModulePkg/Bus/I2c/I2cDxe/I2cDxe.inf INF OpenPlatformPkg/Drivers/I2c/Devices/MvEeprom/MvEeprom.inf INF OpenPlatformPkg/Drivers/Spi/MvSpiDxe.inf + INF OpenPlatformPkg/Drivers/Spi/Devices/MvSpiFlash.inf
# Multiple Console IO support INF MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
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 zcmd6s+ix316vpQniT`1hzLcs>(iZVh#Dn8FZ6xP{?KD&rRf$uFh~`4#P%81a1K)3s zPv)|=6%a_(%GuqyocYdoE^}t{*Pm<Q(Pw>q8NLYJa2c+`r*Iw4!fE(9OhXeMs`V?~ zpM~}CG<>6{op7WPzlHbVgRUlQhYO8-ueJ;IOf~m1KGE0L`$<?0Nat72-3Y_58ONQ4 zv1D9?8~ts<o^ZG%pSv9<>iHz;x4K_z95c=$k`uK|h4@VKo3N$(hbU*FahKs-ZRN_3 z)#8%Qh5D1;(H)JadTO)=NEpXTCsFcL&u8ISedyb0-i3PBH2ykjcdjQ!PNKYdcy8ki zxH7y*nP?VFUWSjFdm-i<y(K=p%{V?6F5`1B7niZ`*j$e$N^Ue4_O2syY0Po##j5ZC zo@;S-6SW5un!pdJ{T(^5m2?Jivj5}A2r|*}N`H}wEcC!$S8BPG_0IHWEv$ot<=l)l z3*M1s+G2BG>0Gj=;l-WDHR{W+M|xYv9I`H>r<Gi>Dmc*?-vA}LO|>!>N|=x2A?U?e zX4MgOp*E1?y~a|G&!3a`;0v~%;aa3WoFo+Uyvn?IEbjs{OkHQO=_~vFK1`YB^Zlo0 z%Itk2_Ru^bUCtNL?}+ky$)ZWK=>LED@<_ry@1vLHsQmdvHXch;I3_!$xbUd6tbwnY zBw~w9WKn*mrw_9FyeRPqOboWOlf^~KyN=86*mhUgEVj#hL>33P$3dAn8|h=2z;N?! z<5T1yl{fR$JZmzO9?!YQOE|O)Y(7m!hDmruf}w*m^D45C<>cJU3<Xh3-X<cEmiB}c zW5oJI5<W^7%UI5`<+(*(coQ?*Skfo@jc0gZ-*P4ETE-(oq%3$N9cmkm!Yl2iLya41 z|Jw?qa2PtuRXw#>`@Y`x!fU;4s&!NC8{v)qGLunV_3o=>pb;<CHd5Owwe{opL6qH* z-I>YQU5#MuMmW&Zo}O8KMXPdW%@y5k1`P1TdcE+2)&bctj$|g|chuU~-LM(@L7X*; zt;4vZY)eX4;|_#_=a;e7FyNJY5jS#n^c&5jfsftTbuCu|-MsavB(^kbM^Xk__0<eb zM>=mutfQ!rv$7Re+`ZFmE3yIyjda5rXwnt-ete_#K&|^4H`FXf!V7rNZWuM~=m`Xy z%C_*dtH0<8ldtu|4p<#@eO*b*c^2K1rXYlKV}7wMH#CkaY+I5ybmz@<%IyhKP<Mp` zjzKuDt*ah954<2{>`=NhlNGE5@952Z0XE*maXC_$`d+-5B%9eta!0c|@(271d=Dd% zfA1?6FIWrhuz)dbJ~31~^(Ph`=^0OJwECW|O|?6_pdG}h>*{G3zKz)W8s*-PhaKpx z7d1r>_<<eM+Hja}G2h$q`C-)2BMIigG0=4&X2C|BQh^i6hw8&)uzgo+*s8>{doZJO z+giMUgUB__-5*i}fb~!-^t2*>EuQhy<XfFP|9~^{2L6(~tCVJ%TUHq@v?g)T6Xzhp z?qmk6V6({thUQTH@Cy(46mOP0Jf1u^kp)asEb1D2)-b;ERwTh!opWKtqmwnTaYueZ z_5}%?8=EfMasar>+>*SF{8RdQ+Mz%1)8Sg=2%gr$cj3X^+k;q3a%N$d<$T7)PW>eM zCc6o5r}0E{qnc?Yn@d&84ryl|^Qw2z4@Ti#w0vJN@J@Wg{`@N;xYgc$s@3ZCZN(Mk zUM$5K2%PKst;kYGaVKWyCX;RJK8ZSk)hd|tSglZdtZK$vA$}{wNh*08KPG$iTK$|g zjx={owS`p!AUshURbi?|)*=sf_G}|rZOL5~Ue+DT+u2L@^@L~E_?lLW>Hp)ba-srj z!XNrk_kgr~qpq>DG-Gld%J*^{6&K99>^3U1=B-c|7d|p?ahX49<ywO4kLI2w@1wn~ z+ZQstjta2$t0!vNjkP=6T<guwUB@~dQ)Aw!#q5NB_(hG)BzDwu5?Q6%D_3ESy5G)H z)Jr?r3ao@>)?|gtnSI=Q=C8Xa51vHsr`4*BqLQqY_or$YZBKQ9!(-AkZ~J3n;Gg5$ znt9Z|w5j<AUurj&-3xrp<fqPqoylx;S$V@-?osn1Z?SJt$zTntT6X9*-*rnp<3(#u zH=Y~E;TLJjsliWiXhjR2!ZRlezH?X%B`dXUQDeZ<EXM6Dgk9?~1GQPKKi8MNMqezF zZ>P1^!|ximes_5!v@zrsa1X}1oOa77K<3jsiR&$734OA2J%{XFBSVkHS~8w5n9DS! z->?5l)8}^*@2_b-$22XGxh}P~J^792+>)_HS`*zVQ<QVyYEkspD<_-fdA}{MZmH!Q zN(0WzM1p;5UhJ18C+2JJd1Nok2J<|1v0r|jS!<cS@?8*}N-VULl1!Ug+k;~7vzS<9 zshT<Bis;HUo?pQ%);5pq8e6hxnLXP$Xvrm^D^XNSOc{q6?&Hh!UFLy#zDfH7zWhwz ze!XQ?c@1Bvu_Wz0$M_8DvH3DA62X+?uO*i@E%&Eo_Q_>h4oa0FPhNxdqdvD{a8<0+ zUL#1lm6mJIEH$xJYiV9(aen5EJWyryT6-d2Z|=7v<};gOZhLP8J5_B@^82ywKhSy5 zPTicx%WD*OQX*ljSg@~YRH)=YuiUR<?Mg<WuC*R){;R42_E_s_SJyQXzMgO<^{-JS k5;8CU%b-^LC{%7O+kg4mZQuLsoWobqbfzd7=Y+-YZ<!+^rT_o{
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
From: Jan Dąbroś jsd@semihalf.com
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 --- Platforms/Marvell/Armada/Armada.dsc.inc | 1 + 1 file changed, 1 insertion(+)
diff --git a/Platforms/Marvell/Armada/Armada.dsc.inc b/Platforms/Marvell/Armada/Armada.dsc.inc index 9b1fc7a..0e234ef 100644 --- a/Platforms/Marvell/Armada/Armada.dsc.inc +++ b/Platforms/Marvell/Armada/Armada.dsc.inc @@ -436,6 +436,7 @@ NULL|ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1CommandsLib.inf NULL|ShellPkg/Library/UefiShellTftpCommandLib/UefiShellTftpCommandLib.inf NULL|OpenPlatformPkg/Applications/EepromCmd/EepromCmd.inf + NULL|OpenPlatformPkg/Applications/SpiTool/SpiFlashCmd.inf HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.inf
From: Jan Dąbroś jsd@semihalf.com
'fupdate' command performs updating firmware from file placed on local filesystem or on TFTP server. It uses tftp and sf commands.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jan Dabros jsd@semihalf.com Signed-off-by: Marcin Wojtas mw@semihalf.com --- Applications/FirmwareUpdate/FUpdate.c | 448 ++++++++++++++++++++++++++++++++ Applications/FirmwareUpdate/FUpdate.inf | 68 +++++ Applications/FirmwareUpdate/FUpdate.uni | Bin 0 -> 5838 bytes Platforms/Marvell/Marvell.dec | 1 + 4 files changed, 517 insertions(+) create mode 100644 Applications/FirmwareUpdate/FUpdate.c create mode 100644 Applications/FirmwareUpdate/FUpdate.inf create mode 100644 Applications/FirmwareUpdate/FUpdate.uni
diff --git a/Applications/FirmwareUpdate/FUpdate.c b/Applications/FirmwareUpdate/FUpdate.c new file mode 100644 index 0000000..359a4ac --- /dev/null +++ b/Applications/FirmwareUpdate/FUpdate.c @@ -0,0 +1,448 @@ +/******************************************************************************* +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/DebugLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/ShellCommandLib.h> +#include <Library/ShellLib.h> +#include <Library/UefiLib.h> +#include <Library/PrintLib.h> +#include <Library/UefiLib.h> +#include <Library/ShellCEntryLib.h> +#include <Library/HiiLib.h> +#include <Guid/ShellLibHiiGuid.h> +#include <Library/UefiBootServicesTableLib.h> +#include <Library/FileHandleLib.h> +// FIXME: Remove including relative path +#include "../../../ShellPkg/Application/Shell/Shell.h" + +#define CMD_NAME_STRING L"fupdate" + +#define TFTP_CMD_STRING L"tftp " +#define SPACE_STRING L" " +#define SF_PROBE_CMD_STRING L"sf probe" +#define SF_WRITE_CMD_STRING L"sf updatefile " +#define SF_LOAD_ADDR_STRING L"0x0" + +#define MAIN_HDR_MAGIC 0xB105B002 + +typedef struct { + 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_IMAGE_HEADER; + +STATIC +UINT32 +CountChecksum ( + UINT32 *Start, + UINT32 Length + ) +{ + UINT32 Sum = 0; + UINT32 *Startp = Start; + + do { + Sum += *Startp; + Startp++; + Length -= 4; + } while (Length > 0); + + return Sum; +} + +STATIC +EFI_STATUS +CheckImageHeader ( + IN VOID *ImageHeader + ) +{ + MV_IMAGE_HEADER *Header; + UINT32 HeaderLength, Checksum, ChecksumBackup; + + Header = (MV_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 = CountChecksum((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 +CheckFirmwareImage ( + CONST CHAR16* FirmwareImage + ) +{ + EFI_STATUS Status; + VOID *FileBuffer; + UINT64 OpenMode; + UINTN FileSize; + SHELL_FILE_HANDLE FileHandle = NULL; + + OpenMode = EFI_FILE_MODE_READ; + + Status = ShellOpenFileByName (FirmwareImage, &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); + } + + FileBuffer = AllocateZeroPool (FileSize); + + // Read Image header into buffer + Status = FileHandleRead (FileHandle, &FileSize, FileBuffer); + if (EFI_ERROR (Status)) { + Print (L"%s: Cannot read Image file header\n", CMD_NAME_STRING); + ShellCloseFile (&FileHandle); + FreePool (FileBuffer); + return EFI_DEVICE_ERROR; + } + + Status = CheckImageHeader (FileBuffer); + if (EFI_ERROR(Status)) { + return EFI_DEVICE_ERROR; + } + + FreePool (FileBuffer); + + return EFI_SUCCESS; +} + +STATIC +CONST CHAR16 * +FileNameFromFilePath ( + CONST CHAR16 *RemoteFilePath + ) +{ + CONST CHAR16 *Walker; + + // Gather FileName from FilePath + Walker = RemoteFilePath + StrLen (RemoteFilePath); + while ((--Walker) >= RemoteFilePath) { + if ((*Walker == L'\') || (*Walker == L'/')) { + break; + } + } + + return (Walker + 1); +} + +STATIC +CONST CHAR16* +PrepareFile ( + LIST_ENTRY *CheckPackage + ) +{ + EFI_STATUS Status; + CONST CHAR16 *ValueStr; + + ValueStr = ShellCommandLineGetValue (CheckPackage, L"-f"); + if (ValueStr == NULL) { + Print (L"%s: No LocalFilePath parameter!\n", CMD_NAME_STRING); + return NULL; + } else { + Status = ShellIsFile (ValueStr); + if (EFI_ERROR(Status)) { + Print (L"%s: Wrong LocalFilePath parameter!\n", CMD_NAME_STRING); + return NULL; + } + } + return ValueStr; +} + +CONST CHAR16 gShellFUpdateFileName[] = L"ShellCommand"; +EFI_HANDLE gShellFUpdateHiiHandle = NULL; +EFI_HANDLE gShellFUpdateHiiHandle; + +STATIC CONST SHELL_PARAM_ITEM ParamList[] = { + {L"help", TypeFlag}, + {L"-t", TypeFlag}, + {L"-f", TypeValue}, + {NULL , TypeMax} + }; + +/** + Return the file name of the help text file if not using HII. + + @return The string pointer to the file name. +**/ +CONST CHAR16* +EFIAPI +ShellCommandGetManFileNameFUpdate ( + VOID + ) +{ + + return gShellFUpdateFileName; +} + +VOID +FUpdateUsage ( + VOID + ) +{ + Print (L"\nFirmware update command\n" + "fupdate [-f <LocalFilePath>] [-t <Host> <RemoteFilePath>]\n\n" + "LocalFilePath - path to local firmware image file\n" + "Host - IP number of TFTP server\n" + "RemoteFilePath - path to firmware image file on TFTP server\n" + "Examples:\n" + "Update firmware from file fs2:Uefi.img\n" + " fupdate -f fs2:Uefi.img\n" + "Update firmware from file path/Uefi.img TFTP server with IP " + "address 10.0.0.200\n" + " fupdate -t 10.0.0.200 path/Uefi.img\n" + ); +} + +SHELL_STATUS +EFIAPI +ShellCommandRunFUpdate ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + LIST_ENTRY *CheckPackage; + CHAR16 *ProblemParam, *TftpCmd = NULL, *SfCmd = NULL; + CONST CHAR16 *RemoteFilePath, *Host, *FileToWrite; + UINT8 CmdLen; + BOOLEAN FileFlag, TftpFlag; + + Status = ShellInitialize (); + if (EFI_ERROR (Status)) { + Print (L"%s: Error while initializinf Shell\n", CMD_NAME_STRING); + ASSERT_EFI_ERROR (Status); + return SHELL_ABORTED; + } + + Status = ShellCommandLineParse (ParamList, &CheckPackage, &ProblemParam, + TRUE); + if (EFI_ERROR (Status)) { + Print (L"Parse error!\n"); + } + + if (ShellCommandLineGetFlag (CheckPackage, L"help")) { + FUpdateUsage(); + return EFI_SUCCESS; + } + + FileFlag = ShellCommandLineGetFlag (CheckPackage, L"-f"); + TftpFlag = ShellCommandLineGetFlag (CheckPackage, L"-t"); + + if (!FileFlag && !TftpFlag) { + Print (L"%s: Please specify -f or -t flag\n", CMD_NAME_STRING); + return SHELL_ABORTED; + } else if (FileFlag && !TftpFlag) { + // Prepare local file to be burned into flash + FileToWrite = PrepareFile (CheckPackage); + if (FileToWrite == NULL) { + Print (L"%s: Error while preparing file for burn\n", CMD_NAME_STRING); + return SHELL_ABORTED; + } + } else if (TftpFlag && !FileFlag) { + Host = ShellCommandLineGetRawValue (CheckPackage, 1); + if (Host == NULL) { + Print (L"%s: No Host parameter!\n", CMD_NAME_STRING); + return SHELL_ABORTED; + } + + RemoteFilePath = ShellCommandLineGetRawValue (CheckPackage, 2); + if (RemoteFilePath == NULL) { + Print (L"%s: No remote_file_path parameter!\n", CMD_NAME_STRING); + return SHELL_ABORTED; + } + + // Gather firmware image name from remote filepath + FileToWrite = FileNameFromFilePath (RemoteFilePath); + + // Allocate buffer for tftp command string + CmdLen = StrSize (TFTP_CMD_STRING) + StrSize (SPACE_STRING) + + StrSize (Host) + StrSize (RemoteFilePath); + TftpCmd = (CHAR16 *) AllocateZeroPool (CmdLen + sizeof(CHAR16)); + if (TftpCmd == NULL) { + Print (L"%s: Cannot allocate memory\n", CMD_NAME_STRING); + return SHELL_ABORTED; + } + + // Concatenate parameters and form tftp command string + StrCatS (TftpCmd, CmdLen / sizeof(CHAR16), TFTP_CMD_STRING); + StrCatS (TftpCmd, CmdLen / sizeof(CHAR16), (CHAR16 *)Host); + // Insert space + StrCatS (TftpCmd, CmdLen / sizeof(CHAR16), SPACE_STRING); + StrCatS (TftpCmd, CmdLen / sizeof(CHAR16), (CHAR16 *)RemoteFilePath); + + RunShellCommand (TftpCmd, &Status); + FreePool (TftpCmd); + if (EFI_ERROR(Status)) { + Print (L"%s: Error while performing tftp command\n", CMD_NAME_STRING); + return SHELL_ABORTED; + } + + } else { + Print (L"%s: Both -f and -t flag specified, please choose one\n", + CMD_NAME_STRING); + return SHELL_ABORTED; + } + + // Check image checksum and magic + Status = CheckFirmwareImage (FileToWrite); + if (EFI_ERROR(Status)) { + Print (L"%s: Wrong firmware Image\n", CMD_NAME_STRING); + return SHELL_ABORTED; + } + + // Probe spi bus + RunShellCommand (SF_PROBE_CMD_STRING, &Status); + if (EFI_ERROR(Status)) { + Print (L"%s: Error while performing sf probe\n", CMD_NAME_STRING); + return SHELL_ABORTED; + } + + // Allocate buffer for sf command string + CmdLen = StrSize (SF_WRITE_CMD_STRING) + StrSize (FileToWrite) + + StrSize (SPACE_STRING) + StrSize (SF_LOAD_ADDR_STRING); + SfCmd = (CHAR16 *) AllocateZeroPool (CmdLen + sizeof(CHAR16)); + if (SfCmd == NULL) { + Print (L"%s: Cannot allocate memory\n"); + return SHELL_ABORTED; + } + + // Concatenate parameters and form command string + StrCatS (SfCmd, CmdLen / sizeof(CHAR16), SF_WRITE_CMD_STRING); + StrCatS (SfCmd, CmdLen / sizeof(CHAR16), (CHAR16 *)FileToWrite); + StrCatS (SfCmd, CmdLen / sizeof(CHAR16), SPACE_STRING); + StrCatS (SfCmd, CmdLen / sizeof(CHAR16), SF_LOAD_ADDR_STRING); + + // Update firmware image in flash + RunShellCommand (SfCmd, &Status); + FreePool (SfCmd); + if (EFI_ERROR(Status)) { + Print (L"%s: Error while performing sf update\n", CMD_NAME_STRING); + return SHELL_ABORTED; + } + + return EFI_SUCCESS; +} + +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/Applications/FirmwareUpdate/FUpdate.inf b/Applications/FirmwareUpdate/FUpdate.inf new file mode 100644 index 0000000..53b5305 --- /dev/null +++ b/Applications/FirmwareUpdate/FUpdate.inf @@ -0,0 +1,68 @@ +# +# 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 = 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] + 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 + +[Guids] + gShellFUpdateHiiGuid diff --git a/Applications/FirmwareUpdate/FUpdate.uni b/Applications/FirmwareUpdate/FUpdate.uni new file mode 100644 index 0000000000000000000000000000000000000000..6143c0580f1d1ef8ce4fe619a1df1ce380adf2c0 GIT binary patch literal 5838 zcmd6r?N1v=5XSd&rTz~m@+FOuK&z@BXdB5G6OhbHeI_(&s)*P?EX6>LDdL}R`}}4Y z_Fim)B2|h`_TBEy&OY<Z%kJL4|E#8GU-k8E`X+VLMY>G4X_hAGEPYJ#RHUcs{Z98E z(pvgH{iLVebS#O#(@FZIt4KTPT#_g1JJ*}J#$MPH@A_(w)60Z*e$BBPsZ5(DH%TMu zI8RslFVenngr*p~lTP*KR@$$1pGl4p6GJjq&s>Nn8egO>-9MS0Q^{SVsru?OKUYs^ znhN!;+Src8b3GNB10={X)7Ui6^*l)*^bUIqjXT$yRmsoHx~ZO!JT-lb@LbynxN^K` zIn^kbyht}1doJb+wK5;k=NwOk%lRBE#O3S<wy>ix&4tFo-prWGG9T<MUWEtn%*5H1 zSq~;Gfgeyu8$Ga<Z3c1n|8rvmo!EG(e{`Y?JMh~dM@OiCW&nJZN~Bn~_GrJG$Ij zd>%7RrE8wn?<20zyXy5!t%sOH*M&t|ohxPqCl(VMpv1PhX2wGq^RXfXyO3p6Go#Mc z2Xdm<S*qfT=Nvu6g3sr;me~&{8O5Tg@+clDy1)!mvr2Bp%yEAVQ*Qa<_-Qib{vL}x zEYC<E=8NnPMAdtpMc3xp|Nrt8nS_5%EXt~=;(06|k7OwvQyp_&MAmuLAl6(HxkV-N zET8D<lf1qtOCkd^gYD|%d6DaG;EFrG-4iy??Rq_;ii11ypk6r(+2fVKanpABoH=Nv z<&j#gnvCR4)Z7mbaOf4-W15N#lkkcLM+avfRa7Cb$<-)x6l5)Rn~X$TUK4VTk?W_@ za3fp1Vg<`y=axm`l~uNpw4drXy2AteUMrc`D;^ahSHUaU(DczTZEGzpC0A<w+e*W9 zlsc+aJ@t71fm-|Njar-P-BkZZdaHj%BGuK~1N96f@mhUD^=+%KZ}J1v-I3oJiR_*v zkljd!dfL}Bv#)4Y?##KOyN`eYo|vzfe%Cx8D@~G-$nUDRue)P&^aC3;wBFKIlpSg5 zO72iNcz$iYj)AD$H{9si)o*yG4ScM|VQYOh&@Gyeoy3+#?Mll)vu@v^>B#0C!#XsJ zf|V_saqr%;En@`^3fYD?u%s*OeQVKssNMs~l^TU4ynqMmO0%@1ClG9^+QQSG{;?A# z-{^-Q@H*)Fy0VpvJi0GSK?vv0{BmDzNRD0Djx=xRPRnho`V*v}?g|GSgK$w_S8s?s z@PZWCQnoXa8N7$+=-tHvY`itODpHvGO}x1#A6ZCqN25B52jU8RPYubJ$BO3*-oiRO z;7of=l<H^yiARTeCejMczOQRj{lPA12bOhRJ(cNa!`7EnL_ZOBs8-J`#SZv^9k<$X zcx*8~`ic3{Y>Z5Td2kGL9g117k*Dmy$>bxwBVzD<S9AER<a0zY(pBGjzJP<wb;~0j zat46)NHg>_BmbVy#A%ML&V78q8Fhnr$<bBU=9YU^87}oEdC(K*Aj0od2E5>-sRWMZ zNblhn9*8MgUOOV6qBc<l+)_Lm7Dv@^zN)=wg0E)Hg^|ck=D^1t#Rb(DByjF*hHkF` z;HuY_9BtH}dYtDK`s+R&t{O-1w3>cRPwrb!Y%j@~g;kdG85b+{3yV!w6Iy3>qPfzZ zX{9ojT`eo5pLsm0-dh|D(|hxLUpeqz+>;BQS42nq$~dmIf}d&5CJLW-MHLu-u?x7? zdOVi2?;F<Cx1yOQLNu-H0}g9a>}aO8dtoo~QX}3;{+%qy`l;i@HPx)wdSBPauAx3( z>^nf%KE)1&a40S~$+4?pPs1L58H!T5z)Evq`BJvzidIjPmp|l5{Q8S>lszr`Qdr`A zePHZ;Os~?Pl0b59lG~ERx38?lX)E?;i$*TP4(h0Xk3mjUJT#X_%?n8_X0gin<(*~h zvDtgF@4S(hIi(+~mG|D+OX0buJ?&^+)>Dm0=76ngbhQ19reJ%S)<S+^oo4sxJJnmY zGY6%`kVg`g?m$uXqa?6%tocvmOTIZQvTJ!v1RCa!I0-gk(Id$@uiD7@iqnDTaIo8+ zyV>(n7Ls@DKFB<FqO7V-xpu@iN36HTd@g76i6Zb~*Ok7Rt*dfT7boHmyUtp=;i;K( zo^g-W@FnOXzE@lLs*zExG5O1n$4E0i3Vj`1la=w~d*Rw6t)*%#8qJA``utI=&gXax z|FhF$H#bn-d!tC;obk9gsE#aZW7`pd*NC^C^!K$wv6t-H-o^KX5&g~k(7qbL-AH!% z2@qzF6)k>Vp2}uwYkVd1H)P>oTCvDQf3r9rtC-mFvyX}sR8P6g7q^*ax)F|8UHrt% QHyJ;b`f6NX>FQbZ9}*T`00000
literal 0 HcmV?d00001
diff --git a/Platforms/Marvell/Marvell.dec b/Platforms/Marvell/Marvell.dec index e63add4..f9d2660 100644 --- a/Platforms/Marvell/Marvell.dec +++ b/Platforms/Marvell/Marvell.dec @@ -54,6 +54,7 @@
gShellEepromHiiGuid = { 0xb2f4c714, 0x147f, 0x4ff7, { 0x82, 0x1b, 0xce, 0x7b, 0x91, 0x7f, 0x5f, 0x2f } } gShellSfHiiGuid = { 0x03a67756, 0x8cde, 0x4638, { 0x82, 0x34, 0x4a, 0x0f, 0x6d, 0x58, 0x81, 0x39 } } + gShellFUpdateHiiGuid = { 0x9b5d2176, 0x590a, 0x49db, { 0x89, 0x5d, 0x4a, 0x70, 0xfe, 0xad, 0xbe, 0x24 } }
[PcdsFixedAtBuild.common] #MPP
On 10 July 2016 at 00:21, Marcin Wojtas mw@semihalf.com wrote:
From: Jan Dąbroś jsd@semihalf.com
'fupdate' command performs updating firmware from file placed on local filesystem or on TFTP server. It uses tftp and sf commands.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jan Dabros jsd@semihalf.com Signed-off-by: Marcin Wojtas mw@semihalf.com
Please use the Shell dynamic command protocol to add commands to the shell. This will remove the need for including internal Shell headers, and even allow your commands to work with prebuilt Shell binaries.
MdePkg/Include/Protocol/ShellDynamicCommand.h
Thanks, Ard.
Applications/FirmwareUpdate/FUpdate.c | 448 ++++++++++++++++++++++++++++++++ Applications/FirmwareUpdate/FUpdate.inf | 68 +++++ Applications/FirmwareUpdate/FUpdate.uni | Bin 0 -> 5838 bytes Platforms/Marvell/Marvell.dec | 1 + 4 files changed, 517 insertions(+) create mode 100644 Applications/FirmwareUpdate/FUpdate.c create mode 100644 Applications/FirmwareUpdate/FUpdate.inf create mode 100644 Applications/FirmwareUpdate/FUpdate.uni
diff --git a/Applications/FirmwareUpdate/FUpdate.c b/Applications/FirmwareUpdate/FUpdate.c new file mode 100644 index 0000000..359a4ac --- /dev/null +++ b/Applications/FirmwareUpdate/FUpdate.c @@ -0,0 +1,448 @@ +/******************************************************************************* +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/DebugLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/ShellCommandLib.h> +#include <Library/ShellLib.h> +#include <Library/UefiLib.h> +#include <Library/PrintLib.h> +#include <Library/UefiLib.h> +#include <Library/ShellCEntryLib.h> +#include <Library/HiiLib.h> +#include <Guid/ShellLibHiiGuid.h> +#include <Library/UefiBootServicesTableLib.h> +#include <Library/FileHandleLib.h> +// FIXME: Remove including relative path +#include "../../../ShellPkg/Application/Shell/Shell.h"
+#define CMD_NAME_STRING L"fupdate"
+#define TFTP_CMD_STRING L"tftp " +#define SPACE_STRING L" " +#define SF_PROBE_CMD_STRING L"sf probe" +#define SF_WRITE_CMD_STRING L"sf updatefile " +#define SF_LOAD_ADDR_STRING L"0x0"
+#define MAIN_HDR_MAGIC 0xB105B002
+typedef struct {
- 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_IMAGE_HEADER;
+STATIC +UINT32 +CountChecksum (
- UINT32 *Start,
- UINT32 Length
- )
+{
- UINT32 Sum = 0;
- UINT32 *Startp = Start;
- do {
- Sum += *Startp;
- Startp++;
- Length -= 4;
- } while (Length > 0);
- return Sum;
+}
+STATIC +EFI_STATUS +CheckImageHeader (
- IN VOID *ImageHeader
- )
+{
- MV_IMAGE_HEADER *Header;
- UINT32 HeaderLength, Checksum, ChecksumBackup;
- Header = (MV_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 = CountChecksum((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 +CheckFirmwareImage (
- CONST CHAR16* FirmwareImage
- )
+{
- EFI_STATUS Status;
- VOID *FileBuffer;
- UINT64 OpenMode;
- UINTN FileSize;
- SHELL_FILE_HANDLE FileHandle = NULL;
- OpenMode = EFI_FILE_MODE_READ;
- Status = ShellOpenFileByName (FirmwareImage, &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);
- }
- FileBuffer = AllocateZeroPool (FileSize);
- // Read Image header into buffer
- Status = FileHandleRead (FileHandle, &FileSize, FileBuffer);
- if (EFI_ERROR (Status)) {
Print (L"%s: Cannot read Image file header\n", CMD_NAME_STRING);
ShellCloseFile (&FileHandle);
FreePool (FileBuffer);
return EFI_DEVICE_ERROR;
- }
- Status = CheckImageHeader (FileBuffer);
- if (EFI_ERROR(Status)) {
- return EFI_DEVICE_ERROR;
- }
- FreePool (FileBuffer);
- return EFI_SUCCESS;
+}
+STATIC +CONST CHAR16 * +FileNameFromFilePath (
- CONST CHAR16 *RemoteFilePath
- )
+{
- CONST CHAR16 *Walker;
- // Gather FileName from FilePath
- Walker = RemoteFilePath + StrLen (RemoteFilePath);
- while ((--Walker) >= RemoteFilePath) {
- if ((*Walker == L'\') || (*Walker == L'/')) {
break;
- }
- }
- return (Walker + 1);
+}
+STATIC +CONST CHAR16* +PrepareFile (
- LIST_ENTRY *CheckPackage
- )
+{
- EFI_STATUS Status;
- CONST CHAR16 *ValueStr;
- ValueStr = ShellCommandLineGetValue (CheckPackage, L"-f");
- if (ValueStr == NULL) {
- Print (L"%s: No LocalFilePath parameter!\n", CMD_NAME_STRING);
- return NULL;
- } else {
- Status = ShellIsFile (ValueStr);
- if (EFI_ERROR(Status)) {
Print (L"%s: Wrong LocalFilePath parameter!\n", CMD_NAME_STRING);
return NULL;
- }
- }
- return ValueStr;
+}
+CONST CHAR16 gShellFUpdateFileName[] = L"ShellCommand"; +EFI_HANDLE gShellFUpdateHiiHandle = NULL; +EFI_HANDLE gShellFUpdateHiiHandle;
+STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
- {L"help", TypeFlag},
- {L"-t", TypeFlag},
- {L"-f", TypeValue},
- {NULL , TypeMax}
- };
+/**
- Return the file name of the help text file if not using HII.
- @return The string pointer to the file name.
+**/ +CONST CHAR16* +EFIAPI +ShellCommandGetManFileNameFUpdate (
- VOID
- )
+{
- return gShellFUpdateFileName;
+}
+VOID +FUpdateUsage (
- VOID
- )
+{
- Print (L"\nFirmware update command\n"
"fupdate [-f <LocalFilePath>] [-t <Host> <RemoteFilePath>]\n\n"
"LocalFilePath - path to local firmware image file\n"
"Host - IP number of TFTP server\n"
"RemoteFilePath - path to firmware image file on TFTP server\n"
"Examples:\n"
"Update firmware from file fs2:Uefi.img\n"
" fupdate -f fs2:Uefi.img\n"
"Update firmware from file path/Uefi.img TFTP server with IP "
"address 10.0.0.200\n"
" fupdate -t 10.0.0.200 path/Uefi.img\n"
- );
+}
+SHELL_STATUS +EFIAPI +ShellCommandRunFUpdate (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
+{
- EFI_STATUS Status;
- LIST_ENTRY *CheckPackage;
- CHAR16 *ProblemParam, *TftpCmd = NULL, *SfCmd = NULL;
- CONST CHAR16 *RemoteFilePath, *Host, *FileToWrite;
- UINT8 CmdLen;
- BOOLEAN FileFlag, TftpFlag;
- Status = ShellInitialize ();
- if (EFI_ERROR (Status)) {
- Print (L"%s: Error while initializinf Shell\n", CMD_NAME_STRING);
- ASSERT_EFI_ERROR (Status);
- return SHELL_ABORTED;
- }
- Status = ShellCommandLineParse (ParamList, &CheckPackage, &ProblemParam,
- TRUE);
- if (EFI_ERROR (Status)) {
- Print (L"Parse error!\n");
- }
- if (ShellCommandLineGetFlag (CheckPackage, L"help")) {
- FUpdateUsage();
- return EFI_SUCCESS;
- }
- FileFlag = ShellCommandLineGetFlag (CheckPackage, L"-f");
- TftpFlag = ShellCommandLineGetFlag (CheckPackage, L"-t");
- if (!FileFlag && !TftpFlag) {
- Print (L"%s: Please specify -f or -t flag\n", CMD_NAME_STRING);
- return SHELL_ABORTED;
- } else if (FileFlag && !TftpFlag) {
- // Prepare local file to be burned into flash
- FileToWrite = PrepareFile (CheckPackage);
- if (FileToWrite == NULL) {
Print (L"%s: Error while preparing file for burn\n", CMD_NAME_STRING);
return SHELL_ABORTED;
- }
- } else if (TftpFlag && !FileFlag) {
- Host = ShellCommandLineGetRawValue (CheckPackage, 1);
- if (Host == NULL) {
Print (L"%s: No Host parameter!\n", CMD_NAME_STRING);
return SHELL_ABORTED;
- }
- RemoteFilePath = ShellCommandLineGetRawValue (CheckPackage, 2);
- if (RemoteFilePath == NULL) {
Print (L"%s: No remote_file_path parameter!\n", CMD_NAME_STRING);
return SHELL_ABORTED;
- }
- // Gather firmware image name from remote filepath
- FileToWrite = FileNameFromFilePath (RemoteFilePath);
- // Allocate buffer for tftp command string
- CmdLen = StrSize (TFTP_CMD_STRING) + StrSize (SPACE_STRING) +
StrSize (Host) + StrSize (RemoteFilePath);
- TftpCmd = (CHAR16 *) AllocateZeroPool (CmdLen + sizeof(CHAR16));
- if (TftpCmd == NULL) {
Print (L"%s: Cannot allocate memory\n", CMD_NAME_STRING);
return SHELL_ABORTED;
- }
- // Concatenate parameters and form tftp command string
- StrCatS (TftpCmd, CmdLen / sizeof(CHAR16), TFTP_CMD_STRING);
- StrCatS (TftpCmd, CmdLen / sizeof(CHAR16), (CHAR16 *)Host);
- // Insert space
- StrCatS (TftpCmd, CmdLen / sizeof(CHAR16), SPACE_STRING);
- StrCatS (TftpCmd, CmdLen / sizeof(CHAR16), (CHAR16 *)RemoteFilePath);
- RunShellCommand (TftpCmd, &Status);
- FreePool (TftpCmd);
- if (EFI_ERROR(Status)) {
Print (L"%s: Error while performing tftp command\n", CMD_NAME_STRING);
return SHELL_ABORTED;
- }
- } else {
- Print (L"%s: Both -f and -t flag specified, please choose one\n",
CMD_NAME_STRING);
- return SHELL_ABORTED;
- }
- // Check image checksum and magic
- Status = CheckFirmwareImage (FileToWrite);
- if (EFI_ERROR(Status)) {
- Print (L"%s: Wrong firmware Image\n", CMD_NAME_STRING);
- return SHELL_ABORTED;
- }
- // Probe spi bus
- RunShellCommand (SF_PROBE_CMD_STRING, &Status);
- if (EFI_ERROR(Status)) {
- Print (L"%s: Error while performing sf probe\n", CMD_NAME_STRING);
- return SHELL_ABORTED;
- }
- // Allocate buffer for sf command string
- CmdLen = StrSize (SF_WRITE_CMD_STRING) + StrSize (FileToWrite) +
- StrSize (SPACE_STRING) + StrSize (SF_LOAD_ADDR_STRING);
- SfCmd = (CHAR16 *) AllocateZeroPool (CmdLen + sizeof(CHAR16));
- if (SfCmd == NULL) {
- Print (L"%s: Cannot allocate memory\n");
- return SHELL_ABORTED;
- }
- // Concatenate parameters and form command string
- StrCatS (SfCmd, CmdLen / sizeof(CHAR16), SF_WRITE_CMD_STRING);
- StrCatS (SfCmd, CmdLen / sizeof(CHAR16), (CHAR16 *)FileToWrite);
- StrCatS (SfCmd, CmdLen / sizeof(CHAR16), SPACE_STRING);
- StrCatS (SfCmd, CmdLen / sizeof(CHAR16), SF_LOAD_ADDR_STRING);
- // Update firmware image in flash
- RunShellCommand (SfCmd, &Status);
- FreePool (SfCmd);
- if (EFI_ERROR(Status)) {
- Print (L"%s: Error while performing sf update\n", CMD_NAME_STRING);
- return SHELL_ABORTED;
- }
- return EFI_SUCCESS;
+}
+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/Applications/FirmwareUpdate/FUpdate.inf b/Applications/FirmwareUpdate/FUpdate.inf new file mode 100644 index 0000000..53b5305 --- /dev/null +++ b/Applications/FirmwareUpdate/FUpdate.inf @@ -0,0 +1,68 @@ +# +# 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 = 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]
- 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
+[Guids]
- gShellFUpdateHiiGuid
diff --git a/Applications/FirmwareUpdate/FUpdate.uni b/Applications/FirmwareUpdate/FUpdate.uni new file mode 100644 index 0000000000000000000000000000000000000000..6143c0580f1d1ef8ce4fe619a1df1ce380adf2c0 GIT binary patch literal 5838 zcmd6r?N1v=5XSd&rTz~m@+FOuK&z@BXdB5G6OhbHeI_(&s)*P?EX6>LDdL}R`}}4Y z_Fim)B2|h`_TBEy&OY<Z%kJL4|E#8GU-k8E`X+VLMY>G4X_hAGEPYJ#RHUcs{Z98E z(pvgH{iLVebS#O#(@FZIt4KTPT#_g1JJ*}J#$MPH@A_(w)60Z*e$BBPsZ5(DH%TMu zI8RslFVenngr*p~lTP*KR@$$1pGl4p6GJjq&s>Nn8egO>-9MS0Q^{SVsru?OKUYs^ znhN!;+Src8b3GNB10={X)7Ui6^*l)*^bUIqjXT$yRmsoHx~ZO!JT-lb@LbynxN^K` zIn^kbyht}1doJb+wK5;k=NwOk%lRBE#O3S<wy>ix&4tFo-prWGG9T<MUWEtn%*5H1 zSq~;Gfgeyu8$Ga<Z3c1n|8rvmo!EG(e{`Y?JMh~dM@OiCW&nJZN~Bn~_GrJG$Ij zd>%7RrE8wn?<20zyXy5!t%sOH*M&t|ohxPqCl(VMpv1PhX2wGq^RXfXyO3p6Go#Mc z2Xdm<S*qfT=Nvu6g3sr;me~&{8O5Tg@+clDy1)!mvr2Bp%yEAVQ*Qa<_-Qib{vL}x zEYC<E=8NnPMAdtpMc3xp|Nrt8nS_5%EXt~=;(06|k7OwvQyp_&MAmuLAl6(HxkV-N zET8D<lf1qtOCkd^gYD|%d6DaG;EFrG-4iy??Rq_;ii11ypk6r(+2fVKanpABoH=Nv z<&j#gnvCR4)Z7mbaOf4-W15N#lkkcLM+avfRa7Cb$<-)x6l5)Rn~X$TUK4VTk?W_@ za3fp1Vg<`y=axm`l~uNpw4drXy2AteUMrc`D;^ahSHUaU(DczTZEGzpC0A<w+e*W9 zlsc+aJ@t71fm-|Njar-P-BkZZdaHj%BGuK~1N96f@mhUD^=+%KZ}J1v-I3oJiR_*v zkljd!dfL}Bv#)4Y?##KOyN`eYo|vzfe%Cx8D@~G-$nUDRue)P&^aC3;wBFKIlpSg5 zO72iNcz$iYj)AD$H{9si)o*yG4ScM|VQYOh&@Gyeoy3+#?Mll)vu@v^>B#0C!#XsJ zf|V_saqr%;En@`^3fYD?u%s*OeQVKssNMs~l^TU4ynqMmO0%@1ClG9^+QQSG{;?A# z-{^-Q@H*)Fy0VpvJi0GSK?vv0{BmDzNRD0Djx=xRPRnho`V*v}?g|GSgK$w_S8s?s z@PZWCQnoXa8N7$+=-tHvY`itODpHvGO}x1#A6ZCqN25B52jU8RPYubJ$BO3*-oiRO z;7of=l<H^yiARTeCejMczOQRj{lPA12bOhRJ(cNa!`7EnL_ZOBs8-J`#SZv^9k<$X zcx*8~`ic3{Y>Z5Td2kGL9g117k*Dmy$>bxwBVzD<S9AER<a0zY(pBGjzJP<wb;~0j zat46)NHg>_BmbVy#A%ML&V78q8Fhnr$<bBU=9YU^87}oEdC(K*Aj0od2E5>-sRWMZ zNblhn9*8MgUOOV6qBc<l+)_Lm7Dv@^zN)=wg0E)Hg^|ck=D^1t#Rb(DByjF*hHkF` z;HuY_9BtH}dYtDK`s+R&t{O-1w3>cRPwrb!Y%j@~g;kdG85b+{3yV!w6Iy3>qPfzZ zX{9ojT`eo5pLsm0-dh|D(|hxLUpeqz+>;BQS42nq$~dmIf}d&5CJLW-MHLu-u?x7? zdOVi2?;F<Cx1yOQLNu-H0}g9a>}aO8dtoo~QX}3;{+%qy`l;i@HPx)wdSBPauAx3( z>^nf%KE)1&a40S~$+4?pPs1L58H!T5z)Evq`BJvzidIjPmp|l5{Q8S>lszr`Qdr`A zePHZ;Os~?Pl0b59lG~ERx38?lX)E?;i$*TP4(h0Xk3mjUJT#X_%?n8_X0gin<(*~h zvDtgF@4S(hIi(+~mG|D+OX0buJ?&^+)>Dm0=76ngbhQ19reJ%S)<S+^oo4sxJJnmY zGY6%`kVg`g?m$uXqa?6%tocvmOTIZQvTJ!v1RCa!I0-gk(Id$@uiD7@iqnDTaIo8+ zyV>(n7Ls@DKFB<FqO7V-xpu@iN36HTd@g76i6Zb~*Ok7Rt*dfT7boHmyUtp=;i;K( zo^g-W@FnOXzE@lLs*zExG5O1n$4E0i3Vj`1la=w~d*Rw6t)*%#8qJA``utI=&gXax z|FhF$H#bn-d!tC;obk9gsE#aZW7`pd*NC^C^!K$wv6t-H-o^KX5&g~k(7qbL-AH!% z2@qzF6)k>Vp2}uwYkVd1H)P>oTCvDQf3r9rtC-mFvyX}sR8P6g7q^*ax)F|8UHrt% QHyJ;b`f6NX>FQbZ9}*T`00000
literal 0 HcmV?d00001
diff --git a/Platforms/Marvell/Marvell.dec b/Platforms/Marvell/Marvell.dec index e63add4..f9d2660 100644 --- a/Platforms/Marvell/Marvell.dec +++ b/Platforms/Marvell/Marvell.dec @@ -54,6 +54,7 @@
gShellEepromHiiGuid = { 0xb2f4c714, 0x147f, 0x4ff7, { 0x82, 0x1b, 0xce, 0x7b, 0x91, 0x7f, 0x5f, 0x2f } } gShellSfHiiGuid = { 0x03a67756, 0x8cde, 0x4638, { 0x82, 0x34, 0x4a, 0x0f, 0x6d, 0x58, 0x81, 0x39 } }
- gShellFUpdateHiiGuid = { 0x9b5d2176, 0x590a, 0x49db, { 0x89, 0x5d, 0x4a, 0x70, 0xfe, 0xad, 0xbe, 0x24 } }
[PcdsFixedAtBuild.common]
#MPP
1.8.3.1
+ Jaben, Ruiyu and edk2 list
Hi Ard,
Internal Shell header ("../../../ShellPkg/Application/Shell/Shell.h") was added ONLY for being able to execute shell commands (tftp and our custom SPI flash control) from within a new command. This is now done with: RunShellCommand (TftpCmd, &Status); And it works fine.
Replacing above with: ShellExecute (&ImageHandle, TftpCmd, FALSE, NULL, &Status); allow to get rid of relative include and seems more appropriate, but there is completely no effect of calling it.
I checked in edk2 sources and see no relation between above problem and registering our command with help of ShellDynamicCommand protocol. Unless I don't know something. Anyway, I'll apreciate any hint, how to solve the issue in a nice way.
Best regards, Marcin
2016-11-15 17:09 GMT+01:00 Ard Biesheuvel ard.biesheuvel@linaro.org:
On 10 July 2016 at 00:21, Marcin Wojtas mw@semihalf.com wrote:
From: Jan Dąbroś jsd@semihalf.com
'fupdate' command performs updating firmware from file placed on local filesystem or on TFTP server. It uses tftp and sf commands.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jan Dabros jsd@semihalf.com Signed-off-by: Marcin Wojtas mw@semihalf.com
Please use the Shell dynamic command protocol to add commands to the shell. This will remove the need for including internal Shell headers, and even allow your commands to work with prebuilt Shell binaries.
MdePkg/Include/Protocol/ShellDynamicCommand.h
Thanks, Ard.
Applications/FirmwareUpdate/FUpdate.c | 448 ++++++++++++++++++++++++++++++++ Applications/FirmwareUpdate/FUpdate.inf | 68 +++++ Applications/FirmwareUpdate/FUpdate.uni | Bin 0 -> 5838 bytes Platforms/Marvell/Marvell.dec | 1 + 4 files changed, 517 insertions(+) create mode 100644 Applications/FirmwareUpdate/FUpdate.c create mode 100644 Applications/FirmwareUpdate/FUpdate.inf create mode 100644 Applications/FirmwareUpdate/FUpdate.uni
diff --git a/Applications/FirmwareUpdate/FUpdate.c b/Applications/FirmwareUpdate/FUpdate.c new file mode 100644 index 0000000..359a4ac --- /dev/null +++ b/Applications/FirmwareUpdate/FUpdate.c @@ -0,0 +1,448 @@ +/******************************************************************************* +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/DebugLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/ShellCommandLib.h> +#include <Library/ShellLib.h> +#include <Library/UefiLib.h> +#include <Library/PrintLib.h> +#include <Library/UefiLib.h> +#include <Library/ShellCEntryLib.h> +#include <Library/HiiLib.h> +#include <Guid/ShellLibHiiGuid.h> +#include <Library/UefiBootServicesTableLib.h> +#include <Library/FileHandleLib.h> +// FIXME: Remove including relative path +#include "../../../ShellPkg/Application/Shell/Shell.h"
+#define CMD_NAME_STRING L"fupdate"
+#define TFTP_CMD_STRING L"tftp " +#define SPACE_STRING L" " +#define SF_PROBE_CMD_STRING L"sf probe" +#define SF_WRITE_CMD_STRING L"sf updatefile " +#define SF_LOAD_ADDR_STRING L"0x0"
+#define MAIN_HDR_MAGIC 0xB105B002
+typedef struct {
- 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_IMAGE_HEADER;
+STATIC +UINT32 +CountChecksum (
- UINT32 *Start,
- UINT32 Length
- )
+{
- UINT32 Sum = 0;
- UINT32 *Startp = Start;
- do {
- Sum += *Startp;
- Startp++;
- Length -= 4;
- } while (Length > 0);
- return Sum;
+}
+STATIC +EFI_STATUS +CheckImageHeader (
- IN VOID *ImageHeader
- )
+{
- MV_IMAGE_HEADER *Header;
- UINT32 HeaderLength, Checksum, ChecksumBackup;
- Header = (MV_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 = CountChecksum((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 +CheckFirmwareImage (
- CONST CHAR16* FirmwareImage
- )
+{
- EFI_STATUS Status;
- VOID *FileBuffer;
- UINT64 OpenMode;
- UINTN FileSize;
- SHELL_FILE_HANDLE FileHandle = NULL;
- OpenMode = EFI_FILE_MODE_READ;
- Status = ShellOpenFileByName (FirmwareImage, &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);
- }
- FileBuffer = AllocateZeroPool (FileSize);
- // Read Image header into buffer
- Status = FileHandleRead (FileHandle, &FileSize, FileBuffer);
- if (EFI_ERROR (Status)) {
Print (L"%s: Cannot read Image file header\n", CMD_NAME_STRING);
ShellCloseFile (&FileHandle);
FreePool (FileBuffer);
return EFI_DEVICE_ERROR;
- }
- Status = CheckImageHeader (FileBuffer);
- if (EFI_ERROR(Status)) {
- return EFI_DEVICE_ERROR;
- }
- FreePool (FileBuffer);
- return EFI_SUCCESS;
+}
+STATIC +CONST CHAR16 * +FileNameFromFilePath (
- CONST CHAR16 *RemoteFilePath
- )
+{
- CONST CHAR16 *Walker;
- // Gather FileName from FilePath
- Walker = RemoteFilePath + StrLen (RemoteFilePath);
- while ((--Walker) >= RemoteFilePath) {
- if ((*Walker == L'\') || (*Walker == L'/')) {
break;
- }
- }
- return (Walker + 1);
+}
+STATIC +CONST CHAR16* +PrepareFile (
- LIST_ENTRY *CheckPackage
- )
+{
- EFI_STATUS Status;
- CONST CHAR16 *ValueStr;
- ValueStr = ShellCommandLineGetValue (CheckPackage, L"-f");
- if (ValueStr == NULL) {
- Print (L"%s: No LocalFilePath parameter!\n", CMD_NAME_STRING);
- return NULL;
- } else {
- Status = ShellIsFile (ValueStr);
- if (EFI_ERROR(Status)) {
Print (L"%s: Wrong LocalFilePath parameter!\n", CMD_NAME_STRING);
return NULL;
- }
- }
- return ValueStr;
+}
+CONST CHAR16 gShellFUpdateFileName[] = L"ShellCommand"; +EFI_HANDLE gShellFUpdateHiiHandle = NULL; +EFI_HANDLE gShellFUpdateHiiHandle;
+STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
- {L"help", TypeFlag},
- {L"-t", TypeFlag},
- {L"-f", TypeValue},
- {NULL , TypeMax}
- };
+/**
- Return the file name of the help text file if not using HII.
- @return The string pointer to the file name.
+**/ +CONST CHAR16* +EFIAPI +ShellCommandGetManFileNameFUpdate (
- VOID
- )
+{
- return gShellFUpdateFileName;
+}
+VOID +FUpdateUsage (
- VOID
- )
+{
- Print (L"\nFirmware update command\n"
"fupdate [-f <LocalFilePath>] [-t <Host> <RemoteFilePath>]\n\n"
"LocalFilePath - path to local firmware image file\n"
"Host - IP number of TFTP server\n"
"RemoteFilePath - path to firmware image file on TFTP server\n"
"Examples:\n"
"Update firmware from file fs2:Uefi.img\n"
" fupdate -f fs2:Uefi.img\n"
"Update firmware from file path/Uefi.img TFTP server with IP "
"address 10.0.0.200\n"
" fupdate -t 10.0.0.200 path/Uefi.img\n"
- );
+}
+SHELL_STATUS +EFIAPI +ShellCommandRunFUpdate (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
+{
- EFI_STATUS Status;
- LIST_ENTRY *CheckPackage;
- CHAR16 *ProblemParam, *TftpCmd = NULL, *SfCmd = NULL;
- CONST CHAR16 *RemoteFilePath, *Host, *FileToWrite;
- UINT8 CmdLen;
- BOOLEAN FileFlag, TftpFlag;
- Status = ShellInitialize ();
- if (EFI_ERROR (Status)) {
- Print (L"%s: Error while initializinf Shell\n", CMD_NAME_STRING);
- ASSERT_EFI_ERROR (Status);
- return SHELL_ABORTED;
- }
- Status = ShellCommandLineParse (ParamList, &CheckPackage, &ProblemParam,
- TRUE);
- if (EFI_ERROR (Status)) {
- Print (L"Parse error!\n");
- }
- if (ShellCommandLineGetFlag (CheckPackage, L"help")) {
- FUpdateUsage();
- return EFI_SUCCESS;
- }
- FileFlag = ShellCommandLineGetFlag (CheckPackage, L"-f");
- TftpFlag = ShellCommandLineGetFlag (CheckPackage, L"-t");
- if (!FileFlag && !TftpFlag) {
- Print (L"%s: Please specify -f or -t flag\n", CMD_NAME_STRING);
- return SHELL_ABORTED;
- } else if (FileFlag && !TftpFlag) {
- // Prepare local file to be burned into flash
- FileToWrite = PrepareFile (CheckPackage);
- if (FileToWrite == NULL) {
Print (L"%s: Error while preparing file for burn\n", CMD_NAME_STRING);
return SHELL_ABORTED;
- }
- } else if (TftpFlag && !FileFlag) {
- Host = ShellCommandLineGetRawValue (CheckPackage, 1);
- if (Host == NULL) {
Print (L"%s: No Host parameter!\n", CMD_NAME_STRING);
return SHELL_ABORTED;
- }
- RemoteFilePath = ShellCommandLineGetRawValue (CheckPackage, 2);
- if (RemoteFilePath == NULL) {
Print (L"%s: No remote_file_path parameter!\n", CMD_NAME_STRING);
return SHELL_ABORTED;
- }
- // Gather firmware image name from remote filepath
- FileToWrite = FileNameFromFilePath (RemoteFilePath);
- // Allocate buffer for tftp command string
- CmdLen = StrSize (TFTP_CMD_STRING) + StrSize (SPACE_STRING) +
StrSize (Host) + StrSize (RemoteFilePath);
- TftpCmd = (CHAR16 *) AllocateZeroPool (CmdLen + sizeof(CHAR16));
- if (TftpCmd == NULL) {
Print (L"%s: Cannot allocate memory\n", CMD_NAME_STRING);
return SHELL_ABORTED;
- }
- // Concatenate parameters and form tftp command string
- StrCatS (TftpCmd, CmdLen / sizeof(CHAR16), TFTP_CMD_STRING);
- StrCatS (TftpCmd, CmdLen / sizeof(CHAR16), (CHAR16 *)Host);
- // Insert space
- StrCatS (TftpCmd, CmdLen / sizeof(CHAR16), SPACE_STRING);
- StrCatS (TftpCmd, CmdLen / sizeof(CHAR16), (CHAR16 *)RemoteFilePath);
- RunShellCommand (TftpCmd, &Status);
- FreePool (TftpCmd);
- if (EFI_ERROR(Status)) {
Print (L"%s: Error while performing tftp command\n", CMD_NAME_STRING);
return SHELL_ABORTED;
- }
- } else {
- Print (L"%s: Both -f and -t flag specified, please choose one\n",
CMD_NAME_STRING);
- return SHELL_ABORTED;
- }
- // Check image checksum and magic
- Status = CheckFirmwareImage (FileToWrite);
- if (EFI_ERROR(Status)) {
- Print (L"%s: Wrong firmware Image\n", CMD_NAME_STRING);
- return SHELL_ABORTED;
- }
- // Probe spi bus
- RunShellCommand (SF_PROBE_CMD_STRING, &Status);
- if (EFI_ERROR(Status)) {
- Print (L"%s: Error while performing sf probe\n", CMD_NAME_STRING);
- return SHELL_ABORTED;
- }
- // Allocate buffer for sf command string
- CmdLen = StrSize (SF_WRITE_CMD_STRING) + StrSize (FileToWrite) +
- StrSize (SPACE_STRING) + StrSize (SF_LOAD_ADDR_STRING);
- SfCmd = (CHAR16 *) AllocateZeroPool (CmdLen + sizeof(CHAR16));
- if (SfCmd == NULL) {
- Print (L"%s: Cannot allocate memory\n");
- return SHELL_ABORTED;
- }
- // Concatenate parameters and form command string
- StrCatS (SfCmd, CmdLen / sizeof(CHAR16), SF_WRITE_CMD_STRING);
- StrCatS (SfCmd, CmdLen / sizeof(CHAR16), (CHAR16 *)FileToWrite);
- StrCatS (SfCmd, CmdLen / sizeof(CHAR16), SPACE_STRING);
- StrCatS (SfCmd, CmdLen / sizeof(CHAR16), SF_LOAD_ADDR_STRING);
- // Update firmware image in flash
- RunShellCommand (SfCmd, &Status);
- FreePool (SfCmd);
- if (EFI_ERROR(Status)) {
- Print (L"%s: Error while performing sf update\n", CMD_NAME_STRING);
- return SHELL_ABORTED;
- }
- return EFI_SUCCESS;
+}
+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/Applications/FirmwareUpdate/FUpdate.inf b/Applications/FirmwareUpdate/FUpdate.inf new file mode 100644 index 0000000..53b5305 --- /dev/null +++ b/Applications/FirmwareUpdate/FUpdate.inf @@ -0,0 +1,68 @@ +# +# 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 = 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]
- 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
+[Guids]
- gShellFUpdateHiiGuid
diff --git a/Applications/FirmwareUpdate/FUpdate.uni b/Applications/FirmwareUpdate/FUpdate.uni new file mode 100644 index 0000000000000000000000000000000000000000..6143c0580f1d1ef8ce4fe619a1df1ce380adf2c0 GIT binary patch literal 5838 zcmd6r?N1v=5XSd&rTz~m@+FOuK&z@BXdB5G6OhbHeI_(&s)*P?EX6>LDdL}R`}}4Y z_Fim)B2|h`_TBEy&OY<Z%kJL4|E#8GU-k8E`X+VLMY>G4X_hAGEPYJ#RHUcs{Z98E z(pvgH{iLVebS#O#(@FZIt4KTPT#_g1JJ*}J#$MPH@A_(w)60Z*e$BBPsZ5(DH%TMu zI8RslFVenngr*p~lTP*KR@$$1pGl4p6GJjq&s>Nn8egO>-9MS0Q^{SVsru?OKUYs^ znhN!;+Src8b3GNB10={X)7Ui6^*l)*^bUIqjXT$yRmsoHx~ZO!JT-lb@LbynxN^K` zIn^kbyht}1doJb+wK5;k=NwOk%lRBE#O3S<wy>ix&4tFo-prWGG9T<MUWEtn%*5H1 zSq~;Gfgeyu8$Ga<Z3c1n|8rvmo!EG(e{`Y?JMh~dM@OiCW&nJZN~Bn~_GrJG$Ij zd>%7RrE8wn?<20zyXy5!t%sOH*M&t|ohxPqCl(VMpv1PhX2wGq^RXfXyO3p6Go#Mc z2Xdm<S*qfT=Nvu6g3sr;me~&{8O5Tg@+clDy1)!mvr2Bp%yEAVQ*Qa<_-Qib{vL}x zEYC<E=8NnPMAdtpMc3xp|Nrt8nS_5%EXt~=;(06|k7OwvQyp_&MAmuLAl6(HxkV-N zET8D<lf1qtOCkd^gYD|%d6DaG;EFrG-4iy??Rq_;ii11ypk6r(+2fVKanpABoH=Nv z<&j#gnvCR4)Z7mbaOf4-W15N#lkkcLM+avfRa7Cb$<-)x6l5)Rn~X$TUK4VTk?W_@ za3fp1Vg<`y=axm`l~uNpw4drXy2AteUMrc`D;^ahSHUaU(DczTZEGzpC0A<w+e*W9 zlsc+aJ@t71fm-|Njar-P-BkZZdaHj%BGuK~1N96f@mhUD^=+%KZ}J1v-I3oJiR_*v zkljd!dfL}Bv#)4Y?##KOyN`eYo|vzfe%Cx8D@~G-$nUDRue)P&^aC3;wBFKIlpSg5 zO72iNcz$iYj)AD$H{9si)o*yG4ScM|VQYOh&@Gyeoy3+#?Mll)vu@v^>B#0C!#XsJ zf|V_saqr%;En@`^3fYD?u%s*OeQVKssNMs~l^TU4ynqMmO0%@1ClG9^+QQSG{;?A# z-{^-Q@H*)Fy0VpvJi0GSK?vv0{BmDzNRD0Djx=xRPRnho`V*v}?g|GSgK$w_S8s?s z@PZWCQnoXa8N7$+=-tHvY`itODpHvGO}x1#A6ZCqN25B52jU8RPYubJ$BO3*-oiRO z;7of=l<H^yiARTeCejMczOQRj{lPA12bOhRJ(cNa!`7EnL_ZOBs8-J`#SZv^9k<$X zcx*8~`ic3{Y>Z5Td2kGL9g117k*Dmy$>bxwBVzD<S9AER<a0zY(pBGjzJP<wb;~0j zat46)NHg>_BmbVy#A%ML&V78q8Fhnr$<bBU=9YU^87}oEdC(K*Aj0od2E5>-sRWMZ zNblhn9*8MgUOOV6qBc<l+)_Lm7Dv@^zN)=wg0E)Hg^|ck=D^1t#Rb(DByjF*hHkF` z;HuY_9BtH}dYtDK`s+R&t{O-1w3>cRPwrb!Y%j@~g;kdG85b+{3yV!w6Iy3>qPfzZ zX{9ojT`eo5pLsm0-dh|D(|hxLUpeqz+>;BQS42nq$~dmIf}d&5CJLW-MHLu-u?x7? zdOVi2?;F<Cx1yOQLNu-H0}g9a>}aO8dtoo~QX}3;{+%qy`l;i@HPx)wdSBPauAx3( z>^nf%KE)1&a40S~$+4?pPs1L58H!T5z)Evq`BJvzidIjPmp|l5{Q8S>lszr`Qdr`A zePHZ;Os~?Pl0b59lG~ERx38?lX)E?;i$*TP4(h0Xk3mjUJT#X_%?n8_X0gin<(*~h zvDtgF@4S(hIi(+~mG|D+OX0buJ?&^+)>Dm0=76ngbhQ19reJ%S)<S+^oo4sxJJnmY zGY6%`kVg`g?m$uXqa?6%tocvmOTIZQvTJ!v1RCa!I0-gk(Id$@uiD7@iqnDTaIo8+ zyV>(n7Ls@DKFB<FqO7V-xpu@iN36HTd@g76i6Zb~*Ok7Rt*dfT7boHmyUtp=;i;K( zo^g-W@FnOXzE@lLs*zExG5O1n$4E0i3Vj`1la=w~d*Rw6t)*%#8qJA``utI=&gXax z|FhF$H#bn-d!tC;obk9gsE#aZW7`pd*NC^C^!K$wv6t-H-o^KX5&g~k(7qbL-AH!% z2@qzF6)k>Vp2}uwYkVd1H)P>oTCvDQf3r9rtC-mFvyX}sR8P6g7q^*ax)F|8UHrt% QHyJ;b`f6NX>FQbZ9}*T`00000
literal 0 HcmV?d00001
diff --git a/Platforms/Marvell/Marvell.dec b/Platforms/Marvell/Marvell.dec index e63add4..f9d2660 100644 --- a/Platforms/Marvell/Marvell.dec +++ b/Platforms/Marvell/Marvell.dec @@ -54,6 +54,7 @@
gShellEepromHiiGuid = { 0xb2f4c714, 0x147f, 0x4ff7, { 0x82, 0x1b, 0xce, 0x7b, 0x91, 0x7f, 0x5f, 0x2f } } gShellSfHiiGuid = { 0x03a67756, 0x8cde, 0x4638, { 0x82, 0x34, 0x4a, 0x0f, 0x6d, 0x58, 0x81, 0x39 } }
- gShellFUpdateHiiGuid = { 0x9b5d2176, 0x590a, 0x49db, { 0x89, 0x5d, 0x4a, 0x70, 0xfe, 0xad, 0xbe, 0x24 } }
[PcdsFixedAtBuild.common]
#MPP
1.8.3.1
Marcin and Ard,
It sounds like there is a goal to have a UEFI Application call into an internal shell command.
There is no documented method to programmatically call an internal command. This is not a goal of the current shell implementation. ShellExecute explicitly does not allow running of internal commands (per UEFI Shell Specification 2.2).
Thus I don’t think using ShellDynamicCommandProtocol will help. That protocol is for allowing a driver add a command to the shell's list of available commands.
-Jaben
-----Original Message----- From: Marcin Wojtas [mailto:mw@semihalf.com] Sent: Wednesday, November 16, 2016 8:13 AM To: Ard Biesheuvel ard.biesheuvel@linaro.org Cc: linaro-uefi linaro-uefi@lists.linaro.org; Leif Lindholm leif.lindholm@linaro.org; Neta Zur Hershkovits neta@marvell.com; Yehuda Yitschak yehuday@marvell.com; Haim Boot hayim@marvell.com; Jan Dąbroś jsd@semihalf.com; Bartosz Szczepanek bsz@semihalf.com; edk2-devel-01 edk2-devel@lists.01.org; Carsey, Jaben jaben.carsey@intel.com; Ni, Ruiyu ruiyu.ni@intel.com Subject: Re: [PATCH v6 21/23] Applications/FirmwareUpdate: Add 'fupdate' comand to shell Importance: High
- Jaben, Ruiyu and edk2 list
Hi Ard,
Internal Shell header ("../../../ShellPkg/Application/Shell/Shell.h") was added ONLY for being able to execute shell commands (tftp and our custom SPI flash control) from within a new command. This is now done with: RunShellCommand (TftpCmd, &Status); And it works fine.
Replacing above with: ShellExecute (&ImageHandle, TftpCmd, FALSE, NULL, &Status); allow to get rid of relative include and seems more appropriate, but there is completely no effect of calling it.
I checked in edk2 sources and see no relation between above problem and registering our command with help of ShellDynamicCommand protocol. Unless I don't know something. Anyway, I'll apreciate any hint, how to solve the issue in a nice way.
Best regards, Marcin
2016-11-15 17:09 GMT+01:00 Ard Biesheuvel ard.biesheuvel@linaro.org:
On 10 July 2016 at 00:21, Marcin Wojtas mw@semihalf.com wrote:
From: Jan Dąbroś jsd@semihalf.com
'fupdate' command performs updating firmware from file placed on local filesystem or on TFTP server. It uses tftp and sf commands.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jan Dabros jsd@semihalf.com Signed-off-by: Marcin Wojtas mw@semihalf.com
Please use the Shell dynamic command protocol to add commands to the shell. This will remove the need for including internal Shell headers, and even allow your commands to work with prebuilt Shell binaries.
MdePkg/Include/Protocol/ShellDynamicCommand.h
Thanks, Ard.
Applications/FirmwareUpdate/FUpdate.c | 448
++++++++++++++++++++++++++++++++
Applications/FirmwareUpdate/FUpdate.inf | 68 +++++ Applications/FirmwareUpdate/FUpdate.uni | Bin 0 -> 5838 bytes Platforms/Marvell/Marvell.dec | 1 + 4 files changed, 517 insertions(+) create mode 100644 Applications/FirmwareUpdate/FUpdate.c create mode 100644 Applications/FirmwareUpdate/FUpdate.inf create mode 100644 Applications/FirmwareUpdate/FUpdate.uni
diff --git a/Applications/FirmwareUpdate/FUpdate.c
b/Applications/FirmwareUpdate/FUpdate.c
new file mode 100644 index 0000000..359a4ac --- /dev/null +++ b/Applications/FirmwareUpdate/FUpdate.c @@ -0,0 +1,448 @@
+/*********************************************************
+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/DebugLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/ShellCommandLib.h> +#include <Library/ShellLib.h> +#include <Library/UefiLib.h> +#include <Library/PrintLib.h> +#include <Library/UefiLib.h> +#include <Library/ShellCEntryLib.h> +#include <Library/HiiLib.h> +#include <Guid/ShellLibHiiGuid.h> +#include <Library/UefiBootServicesTableLib.h> +#include <Library/FileHandleLib.h> +// FIXME: Remove including relative path +#include "../../../ShellPkg/Application/Shell/Shell.h"
+#define CMD_NAME_STRING L"fupdate"
+#define TFTP_CMD_STRING L"tftp " +#define SPACE_STRING L" " +#define SF_PROBE_CMD_STRING L"sf probe" +#define SF_WRITE_CMD_STRING L"sf updatefile " +#define SF_LOAD_ADDR_STRING L"0x0"
+#define MAIN_HDR_MAGIC 0xB105B002
+typedef struct {
- 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_IMAGE_HEADER;
+STATIC +UINT32 +CountChecksum (
- UINT32 *Start,
- UINT32 Length
- )
+{
- UINT32 Sum = 0;
- UINT32 *Startp = Start;
- do {
- Sum += *Startp;
- Startp++;
- Length -= 4;
- } while (Length > 0);
- return Sum;
+}
+STATIC +EFI_STATUS +CheckImageHeader (
- IN VOID *ImageHeader
- )
+{
- MV_IMAGE_HEADER *Header;
- UINT32 HeaderLength, Checksum, ChecksumBackup;
- Header = (MV_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 = CountChecksum((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 +CheckFirmwareImage (
- CONST CHAR16* FirmwareImage
- )
+{
- EFI_STATUS Status;
- VOID *FileBuffer;
- UINT64 OpenMode;
- UINTN FileSize;
- SHELL_FILE_HANDLE FileHandle = NULL;
- OpenMode = EFI_FILE_MODE_READ;
- Status = ShellOpenFileByName (FirmwareImage, &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);
- }
- FileBuffer = AllocateZeroPool (FileSize);
- // Read Image header into buffer
- Status = FileHandleRead (FileHandle, &FileSize, FileBuffer);
- if (EFI_ERROR (Status)) {
Print (L"%s: Cannot read Image file header\n", CMD_NAME_STRING);
ShellCloseFile (&FileHandle);
FreePool (FileBuffer);
return EFI_DEVICE_ERROR;
- }
- Status = CheckImageHeader (FileBuffer);
- if (EFI_ERROR(Status)) {
- return EFI_DEVICE_ERROR;
- }
- FreePool (FileBuffer);
- return EFI_SUCCESS;
+}
+STATIC +CONST CHAR16 * +FileNameFromFilePath (
- CONST CHAR16 *RemoteFilePath
- )
+{
- CONST CHAR16 *Walker;
- // Gather FileName from FilePath
- Walker = RemoteFilePath + StrLen (RemoteFilePath);
- while ((--Walker) >= RemoteFilePath) {
- if ((*Walker == L'\') || (*Walker == L'/')) {
break;
- }
- }
- return (Walker + 1);
+}
+STATIC +CONST CHAR16* +PrepareFile (
- LIST_ENTRY *CheckPackage
- )
+{
- EFI_STATUS Status;
- CONST CHAR16 *ValueStr;
- ValueStr = ShellCommandLineGetValue (CheckPackage, L"-f");
- if (ValueStr == NULL) {
- Print (L"%s: No LocalFilePath parameter!\n", CMD_NAME_STRING);
- return NULL;
- } else {
- Status = ShellIsFile (ValueStr);
- if (EFI_ERROR(Status)) {
Print (L"%s: Wrong LocalFilePath parameter!\n",
CMD_NAME_STRING);
return NULL;
- }
- }
- return ValueStr;
+}
+CONST CHAR16 gShellFUpdateFileName[] = L"ShellCommand"; +EFI_HANDLE gShellFUpdateHiiHandle = NULL; +EFI_HANDLE gShellFUpdateHiiHandle;
+STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
- {L"help", TypeFlag},
- {L"-t", TypeFlag},
- {L"-f", TypeValue},
- {NULL , TypeMax}
- };
+/**
- Return the file name of the help text file if not using HII.
- @return The string pointer to the file name.
+**/ +CONST CHAR16* +EFIAPI +ShellCommandGetManFileNameFUpdate (
- VOID
- )
+{
- return gShellFUpdateFileName;
+}
+VOID +FUpdateUsage (
- VOID
- )
+{
- Print (L"\nFirmware update command\n"
"fupdate [-f <LocalFilePath>] [-t <Host> <RemoteFilePath>]\n\n"
"LocalFilePath - path to local firmware image file\n"
"Host - IP number of TFTP server\n"
"RemoteFilePath - path to firmware image file on TFTP server\n"
"Examples:\n"
"Update firmware from file fs2:Uefi.img\n"
" fupdate -f fs2:Uefi.img\n"
"Update firmware from file path/Uefi.img TFTP server with IP "
"address 10.0.0.200\n"
" fupdate -t 10.0.0.200 path/Uefi.img\n"
- );
+}
+SHELL_STATUS +EFIAPI +ShellCommandRunFUpdate (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
+{
- EFI_STATUS Status;
- LIST_ENTRY *CheckPackage;
- CHAR16 *ProblemParam, *TftpCmd = NULL, *SfCmd = NULL;
- CONST CHAR16 *RemoteFilePath, *Host, *FileToWrite;
- UINT8 CmdLen;
- BOOLEAN FileFlag, TftpFlag;
- Status = ShellInitialize ();
- if (EFI_ERROR (Status)) {
- Print (L"%s: Error while initializinf Shell\n", CMD_NAME_STRING);
- ASSERT_EFI_ERROR (Status);
- return SHELL_ABORTED;
- }
- Status = ShellCommandLineParse (ParamList, &CheckPackage,
&ProblemParam,
- TRUE);
- if (EFI_ERROR (Status)) {
- Print (L"Parse error!\n");
- }
- if (ShellCommandLineGetFlag (CheckPackage, L"help")) {
- FUpdateUsage();
- return EFI_SUCCESS;
- }
- FileFlag = ShellCommandLineGetFlag (CheckPackage, L"-f");
- TftpFlag = ShellCommandLineGetFlag (CheckPackage, L"-t");
- if (!FileFlag && !TftpFlag) {
- Print (L"%s: Please specify -f or -t flag\n", CMD_NAME_STRING);
- return SHELL_ABORTED;
- } else if (FileFlag && !TftpFlag) {
- // Prepare local file to be burned into flash
- FileToWrite = PrepareFile (CheckPackage);
- if (FileToWrite == NULL) {
Print (L"%s: Error while preparing file for burn\n",
CMD_NAME_STRING);
return SHELL_ABORTED;
- }
- } else if (TftpFlag && !FileFlag) {
- Host = ShellCommandLineGetRawValue (CheckPackage, 1);
- if (Host == NULL) {
Print (L"%s: No Host parameter!\n", CMD_NAME_STRING);
return SHELL_ABORTED;
- }
- RemoteFilePath = ShellCommandLineGetRawValue (CheckPackage, 2);
- if (RemoteFilePath == NULL) {
Print (L"%s: No remote_file_path parameter!\n",
CMD_NAME_STRING);
return SHELL_ABORTED;
- }
- // Gather firmware image name from remote filepath
- FileToWrite = FileNameFromFilePath (RemoteFilePath);
- // Allocate buffer for tftp command string
- CmdLen = StrSize (TFTP_CMD_STRING) + StrSize (SPACE_STRING) +
StrSize (Host) + StrSize (RemoteFilePath);
- TftpCmd = (CHAR16 *) AllocateZeroPool (CmdLen + sizeof(CHAR16));
- if (TftpCmd == NULL) {
Print (L"%s: Cannot allocate memory\n", CMD_NAME_STRING);
return SHELL_ABORTED;
- }
- // Concatenate parameters and form tftp command string
- StrCatS (TftpCmd, CmdLen / sizeof(CHAR16), TFTP_CMD_STRING);
- StrCatS (TftpCmd, CmdLen / sizeof(CHAR16), (CHAR16 *)Host);
- // Insert space
- StrCatS (TftpCmd, CmdLen / sizeof(CHAR16), SPACE_STRING);
- StrCatS (TftpCmd, CmdLen / sizeof(CHAR16), (CHAR16
*)RemoteFilePath);
- RunShellCommand (TftpCmd, &Status);
- FreePool (TftpCmd);
- if (EFI_ERROR(Status)) {
Print (L"%s: Error while performing tftp command\n",
CMD_NAME_STRING);
return SHELL_ABORTED;
- }
- } else {
- Print (L"%s: Both -f and -t flag specified, please choose one\n",
CMD_NAME_STRING);
- return SHELL_ABORTED;
- }
- // Check image checksum and magic
- Status = CheckFirmwareImage (FileToWrite);
- if (EFI_ERROR(Status)) {
- Print (L"%s: Wrong firmware Image\n", CMD_NAME_STRING);
- return SHELL_ABORTED;
- }
- // Probe spi bus
- RunShellCommand (SF_PROBE_CMD_STRING, &Status);
- if (EFI_ERROR(Status)) {
- Print (L"%s: Error while performing sf probe\n",
CMD_NAME_STRING);
- return SHELL_ABORTED;
- }
- // Allocate buffer for sf command string
- CmdLen = StrSize (SF_WRITE_CMD_STRING) + StrSize (FileToWrite) +
- StrSize (SPACE_STRING) + StrSize (SF_LOAD_ADDR_STRING);
- SfCmd = (CHAR16 *) AllocateZeroPool (CmdLen + sizeof(CHAR16));
- if (SfCmd == NULL) {
- Print (L"%s: Cannot allocate memory\n");
- return SHELL_ABORTED;
- }
- // Concatenate parameters and form command string
- StrCatS (SfCmd, CmdLen / sizeof(CHAR16), SF_WRITE_CMD_STRING);
- StrCatS (SfCmd, CmdLen / sizeof(CHAR16), (CHAR16 *)FileToWrite);
- StrCatS (SfCmd, CmdLen / sizeof(CHAR16), SPACE_STRING);
- StrCatS (SfCmd, CmdLen / sizeof(CHAR16), SF_LOAD_ADDR_STRING);
- // Update firmware image in flash
- RunShellCommand (SfCmd, &Status);
- FreePool (SfCmd);
- if (EFI_ERROR(Status)) {
- Print (L"%s: Error while performing sf update\n",
CMD_NAME_STRING);
- return SHELL_ABORTED;
- }
- return EFI_SUCCESS;
+}
+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/Applications/FirmwareUpdate/FUpdate.inf
b/Applications/FirmwareUpdate/FUpdate.inf
new file mode 100644 index 0000000..53b5305 --- /dev/null +++ b/Applications/FirmwareUpdate/FUpdate.inf @@ -0,0 +1,68 @@ +# +# 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 = 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]
- 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
+[Guids]
- gShellFUpdateHiiGuid
diff --git a/Applications/FirmwareUpdate/FUpdate.uni
b/Applications/FirmwareUpdate/FUpdate.uni
new file mode 100644 index
0000000000000000000000000000000000000000..6143c0580f1d1ef8ce4fe619a1 df1ce380adf2c0
GIT binary patch literal 5838
zcmd6r?N1v=5XSd&rTz~m@+FOuK&z@BXdB5G6OhbHeI_(&s)*P?EX6>LDdL} R`}}4Y
z_Fim)B2|h`_TBEy&OY<Z%kJL4|E#8GU-
k8E`X+VLMY>G4X_hAGEPYJ#RHUcs{Z98E
z(pvgH{iLVebS#O#(@FZIt4KTPT#_g1JJ*}J#$MPH@A_(w)60Z*e$BBPsZ5(DH% TMu
zI8RslFVenngr*p~lTP*KR@$$1pGl4p6GJjq&s>Nn8egO>-
9MS0Q^{SVsru?OKUYs^
znhN!;+Src8b3GNB10={X)7Ui6^*l)*^bUIqjXT$yRmsoHx~ZO!JT-
lb@LbynxN^K`
zIn^kbyht}1doJb+wK5;k=NwOk%lRBE#O3S<wy>ix&4tFo-
prWGG9T<MUWEtn%*5H1
zSq~;Gfgeyu8$Ga<Z3c1n|8rvmo!EG(e{`Y?JMh~dM@OiCW&nJZN~Bn~_Gr JG$Ij
zd>%7RrE8wn?<20zyXy5!t%sOH*M&t|ohxPqCl(VMpv1PhX2wGq^RXfXyO3p 6Go#Mc
z2Xdm<S*qfT=Nvu6g3sr;me~&{8O5Tg@+clDy1)!mvr2Bp%yEAVQ*Qa<_-
Qib{vL}x
zEYC<E=8NnPMAdtpMc3xp|Nrt8nS_5%EXt~=;(06|k7OwvQyp_&MAmuLAl6( HxkV-N
zET8D<lf1qtOCkd^gYD|%d6DaG;EFrG-
4iy??Rq_;ii11ypk6r(+2fVKanpABoH=Nv
z<&j#gnvCR4)Z7mbaOf4-W15N#lkkcLM+avfRa7Cb$<-
)x6l5)Rn~X$TUK4VTk?W_@
za3fp1Vg<`y=axm`l~uNpw4drXy2AteUMrc`D;^ahSHUaU(DczTZEGzpC0A<w+ e*W9
zlsc+aJ@t71fm-|Njar-P-BkZZdaHj%BGuK~1N96f@mhUD^=+%KZ}J1v-
I3oJiR_*v
zkljd!dfL}Bv#)4Y?##KOyN`eYo|vzfe%Cx8D@~G-
$nUDRue)P&^aC3;wBFKIlpSg5
zO72iNcz$iYj)AD$H{9si)o*yG4ScM|VQYOh&@Gyeoy3+#?Mll)vu@v^>B#0C!# XsJ
zf|V_saqr%;En@`^3fYD?u%s*OeQVKssNMs~l^TU4ynqMmO0%@1ClG9^+Q QSG{;?A#
z-{^-
Q@H*)Fy0VpvJi0GSK?vv0{BmDzNRD0Djx=xRPRnho`V*v}?g|GSgK$w_S8s?s
z@PZWCQnoXa8N7$+=-
tHvY`itODpHvGO}x1#A6ZCqN25B52jU8RPYubJ$BO3*-oiRO
z;7of=l<H^yiARTeCejMczOQRj{lPA12bOhRJ(cNa!`7EnL_ZOBs8-
J`#SZv^9k<$X
zcx*8~`ic3{Y>Z5Td2kGL9g117k*Dmy$>bxwBVzD<S9AER<a0zY(pBGjzJP<wb;~ 0j
zat46)NHg>_BmbVy#A%ML&V78q8Fhnr$<bBU=9YU^87}oEdC(K*Aj0od2E5>- sRWMZ
zNblhn9*8MgUOOV6qBc<l+)_Lm7Dv@^zN)=wg0E)Hg^|ck=D^1t#Rb(DByjF* hHkF`
z;HuY_9BtH}dYtDK`s+R&t{O-
1w3>cRPwrb!Y%j@~g;kdG85b+{3yV!w6Iy3>qPfzZ
zX{9ojT`eo5pLsm0-dh|D(|hxLUpeqz+>;BQS42nq$~dmIf}d&5CJLW-MHLu-
u?x7?
zdOVi2?;F<Cx1yOQLNu-
H0}g9a>}aO8dtoo~QX}3;{+%qy`l;i@HPx)wdSBPauAx3(
z>^nf%KE)1&a40S~$+4?pPs1L58H!T5z)Evq`BJvzidIjPmp|l5{Q8S>lszr`Qdr`A
zePHZ;Os~?Pl0b59lG~ERx38?lX)E?;i$*TP4(h0Xk3mjUJT#X_%?n8_X0gin<(*~h
zvDtgF@4S(hIi(+~mG|D+OX0buJ?&^+)>Dm0=76ngbhQ19reJ%S)<S+^oo4sxJJ nmY
zGY6%`kVg`g?m$uXqa?6%tocvmOTIZQvTJ!v1RCa!I0-
gk(Id$@uiD7@iqnDTaIo8+
zyV>(n7Ls@DKFB<FqO7V-
xpu@iN36HTd@g76i6Zb~*Ok7Rt*dfT7boHmyUtp=;i;K(
zo^g-
W@FnOXzE@lLs*zExG5O1n$4E0i3Vj`1la=w~d*Rw6t)*%#8qJA``utI=&gXax
z|FhF$H#bn-d!tC;obk9gsE#aZW7`pd*NC^C^!K$wv6t-H-o^KX5&g~k(7qbL-
AH!%
z2@qzF6)k>Vp2}uwYkVd1H)P>oTCvDQf3r9rtC-
mFvyX}sR8P6g7q^*ax)F|8UHrt%
QHyJ;b`f6NX>FQbZ9}*T`00000
literal 0 HcmV?d00001
diff --git a/Platforms/Marvell/Marvell.dec
b/Platforms/Marvell/Marvell.dec
index e63add4..f9d2660 100644 --- a/Platforms/Marvell/Marvell.dec +++ b/Platforms/Marvell/Marvell.dec @@ -54,6 +54,7 @@
gShellEepromHiiGuid = { 0xb2f4c714, 0x147f, 0x4ff7, { 0x82, 0x1b, 0xce,
0x7b, 0x91, 0x7f, 0x5f, 0x2f } }
gShellSfHiiGuid = { 0x03a67756, 0x8cde, 0x4638, { 0x82, 0x34, 0x4a, 0x0f,
0x6d, 0x58, 0x81, 0x39 } }
- gShellFUpdateHiiGuid = { 0x9b5d2176, 0x590a, 0x49db, { 0x89, 0x5d,
0x4a, 0x70, 0xfe, 0xad, 0xbe, 0x24 } }
[PcdsFixedAtBuild.common]
#MPP
1.8.3.1
Hi Jaben,
I've seen a few different solutions to the same problem of providing platform-specific "shorthand" commands, my least favourite one being embedding a locally hacked EBL.
I guess we're ending up with something halfway between an application and a script.
Is it your view that this should always be implemented as a standalone application, to be called from the UI config menus?
Basically, is there an expected usage pattern that people keep missing?
Regards,
Leif
On Wed, Nov 16, 2016 at 05:05:36PM +0000, Carsey, Jaben wrote:
Marcin and Ard,
It sounds like there is a goal to have a UEFI Application call into an internal shell command.
There is no documented method to programmatically call an internal command. This is not a goal of the current shell implementation. ShellExecute explicitly does not allow running of internal commands (per UEFI Shell Specification 2.2).
Thus I don’t think using ShellDynamicCommandProtocol will help. That protocol is for allowing a driver add a command to the shell's list of available commands.
-Jaben
-----Original Message----- From: Marcin Wojtas [mailto:mw@semihalf.com] Sent: Wednesday, November 16, 2016 8:13 AM To: Ard Biesheuvel ard.biesheuvel@linaro.org Cc: linaro-uefi linaro-uefi@lists.linaro.org; Leif Lindholm leif.lindholm@linaro.org; Neta Zur Hershkovits neta@marvell.com; Yehuda Yitschak yehuday@marvell.com; Haim Boot hayim@marvell.com; Jan Dąbroś jsd@semihalf.com; Bartosz Szczepanek bsz@semihalf.com; edk2-devel-01 edk2-devel@lists.01.org; Carsey, Jaben jaben.carsey@intel.com; Ni, Ruiyu ruiyu.ni@intel.com Subject: Re: [PATCH v6 21/23] Applications/FirmwareUpdate: Add 'fupdate' comand to shell Importance: High
- Jaben, Ruiyu and edk2 list
Hi Ard,
Internal Shell header ("../../../ShellPkg/Application/Shell/Shell.h") was added ONLY for being able to execute shell commands (tftp and our custom SPI flash control) from within a new command. This is now done with: RunShellCommand (TftpCmd, &Status); And it works fine.
Replacing above with: ShellExecute (&ImageHandle, TftpCmd, FALSE, NULL, &Status); allow to get rid of relative include and seems more appropriate, but there is completely no effect of calling it.
I checked in edk2 sources and see no relation between above problem and registering our command with help of ShellDynamicCommand protocol. Unless I don't know something. Anyway, I'll apreciate any hint, how to solve the issue in a nice way.
Best regards, Marcin
2016-11-15 17:09 GMT+01:00 Ard Biesheuvel ard.biesheuvel@linaro.org:
On 10 July 2016 at 00:21, Marcin Wojtas mw@semihalf.com wrote:
From: Jan Dąbroś jsd@semihalf.com
'fupdate' command performs updating firmware from file placed on local filesystem or on TFTP server. It uses tftp and sf commands.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jan Dabros jsd@semihalf.com Signed-off-by: Marcin Wojtas mw@semihalf.com
Please use the Shell dynamic command protocol to add commands to the shell. This will remove the need for including internal Shell headers, and even allow your commands to work with prebuilt Shell binaries.
MdePkg/Include/Protocol/ShellDynamicCommand.h
Thanks, Ard.
Applications/FirmwareUpdate/FUpdate.c | 448
++++++++++++++++++++++++++++++++
Applications/FirmwareUpdate/FUpdate.inf | 68 +++++ Applications/FirmwareUpdate/FUpdate.uni | Bin 0 -> 5838 bytes Platforms/Marvell/Marvell.dec | 1 + 4 files changed, 517 insertions(+) create mode 100644 Applications/FirmwareUpdate/FUpdate.c create mode 100644 Applications/FirmwareUpdate/FUpdate.inf create mode 100644 Applications/FirmwareUpdate/FUpdate.uni
diff --git a/Applications/FirmwareUpdate/FUpdate.c
b/Applications/FirmwareUpdate/FUpdate.c
new file mode 100644 index 0000000..359a4ac --- /dev/null +++ b/Applications/FirmwareUpdate/FUpdate.c @@ -0,0 +1,448 @@
+/*********************************************************
+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/DebugLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/ShellCommandLib.h> +#include <Library/ShellLib.h> +#include <Library/UefiLib.h> +#include <Library/PrintLib.h> +#include <Library/UefiLib.h> +#include <Library/ShellCEntryLib.h> +#include <Library/HiiLib.h> +#include <Guid/ShellLibHiiGuid.h> +#include <Library/UefiBootServicesTableLib.h> +#include <Library/FileHandleLib.h> +// FIXME: Remove including relative path +#include "../../../ShellPkg/Application/Shell/Shell.h"
+#define CMD_NAME_STRING L"fupdate"
+#define TFTP_CMD_STRING L"tftp " +#define SPACE_STRING L" " +#define SF_PROBE_CMD_STRING L"sf probe" +#define SF_WRITE_CMD_STRING L"sf updatefile " +#define SF_LOAD_ADDR_STRING L"0x0"
+#define MAIN_HDR_MAGIC 0xB105B002
+typedef struct {
- 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_IMAGE_HEADER;
+STATIC +UINT32 +CountChecksum (
- UINT32 *Start,
- UINT32 Length
- )
+{
- UINT32 Sum = 0;
- UINT32 *Startp = Start;
- do {
- Sum += *Startp;
- Startp++;
- Length -= 4;
- } while (Length > 0);
- return Sum;
+}
+STATIC +EFI_STATUS +CheckImageHeader (
- IN VOID *ImageHeader
- )
+{
- MV_IMAGE_HEADER *Header;
- UINT32 HeaderLength, Checksum, ChecksumBackup;
- Header = (MV_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 = CountChecksum((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 +CheckFirmwareImage (
- CONST CHAR16* FirmwareImage
- )
+{
- EFI_STATUS Status;
- VOID *FileBuffer;
- UINT64 OpenMode;
- UINTN FileSize;
- SHELL_FILE_HANDLE FileHandle = NULL;
- OpenMode = EFI_FILE_MODE_READ;
- Status = ShellOpenFileByName (FirmwareImage, &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);
- }
- FileBuffer = AllocateZeroPool (FileSize);
- // Read Image header into buffer
- Status = FileHandleRead (FileHandle, &FileSize, FileBuffer);
- if (EFI_ERROR (Status)) {
Print (L"%s: Cannot read Image file header\n", CMD_NAME_STRING);
ShellCloseFile (&FileHandle);
FreePool (FileBuffer);
return EFI_DEVICE_ERROR;
- }
- Status = CheckImageHeader (FileBuffer);
- if (EFI_ERROR(Status)) {
- return EFI_DEVICE_ERROR;
- }
- FreePool (FileBuffer);
- return EFI_SUCCESS;
+}
+STATIC +CONST CHAR16 * +FileNameFromFilePath (
- CONST CHAR16 *RemoteFilePath
- )
+{
- CONST CHAR16 *Walker;
- // Gather FileName from FilePath
- Walker = RemoteFilePath + StrLen (RemoteFilePath);
- while ((--Walker) >= RemoteFilePath) {
- if ((*Walker == L'\') || (*Walker == L'/')) {
break;
- }
- }
- return (Walker + 1);
+}
+STATIC +CONST CHAR16* +PrepareFile (
- LIST_ENTRY *CheckPackage
- )
+{
- EFI_STATUS Status;
- CONST CHAR16 *ValueStr;
- ValueStr = ShellCommandLineGetValue (CheckPackage, L"-f");
- if (ValueStr == NULL) {
- Print (L"%s: No LocalFilePath parameter!\n", CMD_NAME_STRING);
- return NULL;
- } else {
- Status = ShellIsFile (ValueStr);
- if (EFI_ERROR(Status)) {
Print (L"%s: Wrong LocalFilePath parameter!\n",
CMD_NAME_STRING);
return NULL;
- }
- }
- return ValueStr;
+}
+CONST CHAR16 gShellFUpdateFileName[] = L"ShellCommand"; +EFI_HANDLE gShellFUpdateHiiHandle = NULL; +EFI_HANDLE gShellFUpdateHiiHandle;
+STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
- {L"help", TypeFlag},
- {L"-t", TypeFlag},
- {L"-f", TypeValue},
- {NULL , TypeMax}
- };
+/**
- Return the file name of the help text file if not using HII.
- @return The string pointer to the file name.
+**/ +CONST CHAR16* +EFIAPI +ShellCommandGetManFileNameFUpdate (
- VOID
- )
+{
- return gShellFUpdateFileName;
+}
+VOID +FUpdateUsage (
- VOID
- )
+{
- Print (L"\nFirmware update command\n"
"fupdate [-f <LocalFilePath>] [-t <Host> <RemoteFilePath>]\n\n"
"LocalFilePath - path to local firmware image file\n"
"Host - IP number of TFTP server\n"
"RemoteFilePath - path to firmware image file on TFTP server\n"
"Examples:\n"
"Update firmware from file fs2:Uefi.img\n"
" fupdate -f fs2:Uefi.img\n"
"Update firmware from file path/Uefi.img TFTP server with IP "
"address 10.0.0.200\n"
" fupdate -t 10.0.0.200 path/Uefi.img\n"
- );
+}
+SHELL_STATUS +EFIAPI +ShellCommandRunFUpdate (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
+{
- EFI_STATUS Status;
- LIST_ENTRY *CheckPackage;
- CHAR16 *ProblemParam, *TftpCmd = NULL, *SfCmd = NULL;
- CONST CHAR16 *RemoteFilePath, *Host, *FileToWrite;
- UINT8 CmdLen;
- BOOLEAN FileFlag, TftpFlag;
- Status = ShellInitialize ();
- if (EFI_ERROR (Status)) {
- Print (L"%s: Error while initializinf Shell\n", CMD_NAME_STRING);
- ASSERT_EFI_ERROR (Status);
- return SHELL_ABORTED;
- }
- Status = ShellCommandLineParse (ParamList, &CheckPackage,
&ProblemParam,
- TRUE);
- if (EFI_ERROR (Status)) {
- Print (L"Parse error!\n");
- }
- if (ShellCommandLineGetFlag (CheckPackage, L"help")) {
- FUpdateUsage();
- return EFI_SUCCESS;
- }
- FileFlag = ShellCommandLineGetFlag (CheckPackage, L"-f");
- TftpFlag = ShellCommandLineGetFlag (CheckPackage, L"-t");
- if (!FileFlag && !TftpFlag) {
- Print (L"%s: Please specify -f or -t flag\n", CMD_NAME_STRING);
- return SHELL_ABORTED;
- } else if (FileFlag && !TftpFlag) {
- // Prepare local file to be burned into flash
- FileToWrite = PrepareFile (CheckPackage);
- if (FileToWrite == NULL) {
Print (L"%s: Error while preparing file for burn\n",
CMD_NAME_STRING);
return SHELL_ABORTED;
- }
- } else if (TftpFlag && !FileFlag) {
- Host = ShellCommandLineGetRawValue (CheckPackage, 1);
- if (Host == NULL) {
Print (L"%s: No Host parameter!\n", CMD_NAME_STRING);
return SHELL_ABORTED;
- }
- RemoteFilePath = ShellCommandLineGetRawValue (CheckPackage, 2);
- if (RemoteFilePath == NULL) {
Print (L"%s: No remote_file_path parameter!\n",
CMD_NAME_STRING);
return SHELL_ABORTED;
- }
- // Gather firmware image name from remote filepath
- FileToWrite = FileNameFromFilePath (RemoteFilePath);
- // Allocate buffer for tftp command string
- CmdLen = StrSize (TFTP_CMD_STRING) + StrSize (SPACE_STRING) +
StrSize (Host) + StrSize (RemoteFilePath);
- TftpCmd = (CHAR16 *) AllocateZeroPool (CmdLen + sizeof(CHAR16));
- if (TftpCmd == NULL) {
Print (L"%s: Cannot allocate memory\n", CMD_NAME_STRING);
return SHELL_ABORTED;
- }
- // Concatenate parameters and form tftp command string
- StrCatS (TftpCmd, CmdLen / sizeof(CHAR16), TFTP_CMD_STRING);
- StrCatS (TftpCmd, CmdLen / sizeof(CHAR16), (CHAR16 *)Host);
- // Insert space
- StrCatS (TftpCmd, CmdLen / sizeof(CHAR16), SPACE_STRING);
- StrCatS (TftpCmd, CmdLen / sizeof(CHAR16), (CHAR16
*)RemoteFilePath);
- RunShellCommand (TftpCmd, &Status);
- FreePool (TftpCmd);
- if (EFI_ERROR(Status)) {
Print (L"%s: Error while performing tftp command\n",
CMD_NAME_STRING);
return SHELL_ABORTED;
- }
- } else {
- Print (L"%s: Both -f and -t flag specified, please choose one\n",
CMD_NAME_STRING);
- return SHELL_ABORTED;
- }
- // Check image checksum and magic
- Status = CheckFirmwareImage (FileToWrite);
- if (EFI_ERROR(Status)) {
- Print (L"%s: Wrong firmware Image\n", CMD_NAME_STRING);
- return SHELL_ABORTED;
- }
- // Probe spi bus
- RunShellCommand (SF_PROBE_CMD_STRING, &Status);
- if (EFI_ERROR(Status)) {
- Print (L"%s: Error while performing sf probe\n",
CMD_NAME_STRING);
- return SHELL_ABORTED;
- }
- // Allocate buffer for sf command string
- CmdLen = StrSize (SF_WRITE_CMD_STRING) + StrSize (FileToWrite) +
- StrSize (SPACE_STRING) + StrSize (SF_LOAD_ADDR_STRING);
- SfCmd = (CHAR16 *) AllocateZeroPool (CmdLen + sizeof(CHAR16));
- if (SfCmd == NULL) {
- Print (L"%s: Cannot allocate memory\n");
- return SHELL_ABORTED;
- }
- // Concatenate parameters and form command string
- StrCatS (SfCmd, CmdLen / sizeof(CHAR16), SF_WRITE_CMD_STRING);
- StrCatS (SfCmd, CmdLen / sizeof(CHAR16), (CHAR16 *)FileToWrite);
- StrCatS (SfCmd, CmdLen / sizeof(CHAR16), SPACE_STRING);
- StrCatS (SfCmd, CmdLen / sizeof(CHAR16), SF_LOAD_ADDR_STRING);
- // Update firmware image in flash
- RunShellCommand (SfCmd, &Status);
- FreePool (SfCmd);
- if (EFI_ERROR(Status)) {
- Print (L"%s: Error while performing sf update\n",
CMD_NAME_STRING);
- return SHELL_ABORTED;
- }
- return EFI_SUCCESS;
+}
+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/Applications/FirmwareUpdate/FUpdate.inf
b/Applications/FirmwareUpdate/FUpdate.inf
new file mode 100644 index 0000000..53b5305 --- /dev/null +++ b/Applications/FirmwareUpdate/FUpdate.inf @@ -0,0 +1,68 @@ +# +# 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 = 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]
- 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
+[Guids]
- gShellFUpdateHiiGuid
diff --git a/Applications/FirmwareUpdate/FUpdate.uni
b/Applications/FirmwareUpdate/FUpdate.uni
new file mode 100644 index
0000000000000000000000000000000000000000..6143c0580f1d1ef8ce4fe619a1 df1ce380adf2c0
GIT binary patch literal 5838
zcmd6r?N1v=5XSd&rTz~m@+FOuK&z@BXdB5G6OhbHeI_(&s)*P?EX6>LDdL} R`}}4Y
z_Fim)B2|h`_TBEy&OY<Z%kJL4|E#8GU-
k8E`X+VLMY>G4X_hAGEPYJ#RHUcs{Z98E
z(pvgH{iLVebS#O#(@FZIt4KTPT#_g1JJ*}J#$MPH@A_(w)60Z*e$BBPsZ5(DH% TMu
zI8RslFVenngr*p~lTP*KR@$$1pGl4p6GJjq&s>Nn8egO>-
9MS0Q^{SVsru?OKUYs^
znhN!;+Src8b3GNB10={X)7Ui6^*l)*^bUIqjXT$yRmsoHx~ZO!JT-
lb@LbynxN^K`
zIn^kbyht}1doJb+wK5;k=NwOk%lRBE#O3S<wy>ix&4tFo-
prWGG9T<MUWEtn%*5H1
zSq~;Gfgeyu8$Ga<Z3c1n|8rvmo!EG(e{`Y?JMh~dM@OiCW&nJZN~Bn~_Gr JG$Ij
zd>%7RrE8wn?<20zyXy5!t%sOH*M&t|ohxPqCl(VMpv1PhX2wGq^RXfXyO3p 6Go#Mc
z2Xdm<S*qfT=Nvu6g3sr;me~&{8O5Tg@+clDy1)!mvr2Bp%yEAVQ*Qa<_-
Qib{vL}x
zEYC<E=8NnPMAdtpMc3xp|Nrt8nS_5%EXt~=;(06|k7OwvQyp_&MAmuLAl6( HxkV-N
zET8D<lf1qtOCkd^gYD|%d6DaG;EFrG-
4iy??Rq_;ii11ypk6r(+2fVKanpABoH=Nv
z<&j#gnvCR4)Z7mbaOf4-W15N#lkkcLM+avfRa7Cb$<-
)x6l5)Rn~X$TUK4VTk?W_@
za3fp1Vg<`y=axm`l~uNpw4drXy2AteUMrc`D;^ahSHUaU(DczTZEGzpC0A<w+ e*W9
zlsc+aJ@t71fm-|Njar-P-BkZZdaHj%BGuK~1N96f@mhUD^=+%KZ}J1v-
I3oJiR_*v
zkljd!dfL}Bv#)4Y?##KOyN`eYo|vzfe%Cx8D@~G-
$nUDRue)P&^aC3;wBFKIlpSg5
zO72iNcz$iYj)AD$H{9si)o*yG4ScM|VQYOh&@Gyeoy3+#?Mll)vu@v^>B#0C!# XsJ
zf|V_saqr%;En@`^3fYD?u%s*OeQVKssNMs~l^TU4ynqMmO0%@1ClG9^+Q QSG{;?A#
z-{^-
Q@H*)Fy0VpvJi0GSK?vv0{BmDzNRD0Djx=xRPRnho`V*v}?g|GSgK$w_S8s?s
z@PZWCQnoXa8N7$+=-
tHvY`itODpHvGO}x1#A6ZCqN25B52jU8RPYubJ$BO3*-oiRO
z;7of=l<H^yiARTeCejMczOQRj{lPA12bOhRJ(cNa!`7EnL_ZOBs8-
J`#SZv^9k<$X
zcx*8~`ic3{Y>Z5Td2kGL9g117k*Dmy$>bxwBVzD<S9AER<a0zY(pBGjzJP<wb;~ 0j
zat46)NHg>_BmbVy#A%ML&V78q8Fhnr$<bBU=9YU^87}oEdC(K*Aj0od2E5>- sRWMZ
zNblhn9*8MgUOOV6qBc<l+)_Lm7Dv@^zN)=wg0E)Hg^|ck=D^1t#Rb(DByjF* hHkF`
z;HuY_9BtH}dYtDK`s+R&t{O-
1w3>cRPwrb!Y%j@~g;kdG85b+{3yV!w6Iy3>qPfzZ
zX{9ojT`eo5pLsm0-dh|D(|hxLUpeqz+>;BQS42nq$~dmIf}d&5CJLW-MHLu-
u?x7?
zdOVi2?;F<Cx1yOQLNu-
H0}g9a>}aO8dtoo~QX}3;{+%qy`l;i@HPx)wdSBPauAx3(
z>^nf%KE)1&a40S~$+4?pPs1L58H!T5z)Evq`BJvzidIjPmp|l5{Q8S>lszr`Qdr`A
zePHZ;Os~?Pl0b59lG~ERx38?lX)E?;i$*TP4(h0Xk3mjUJT#X_%?n8_X0gin<(*~h
zvDtgF@4S(hIi(+~mG|D+OX0buJ?&^+)>Dm0=76ngbhQ19reJ%S)<S+^oo4sxJJ nmY
zGY6%`kVg`g?m$uXqa?6%tocvmOTIZQvTJ!v1RCa!I0-
gk(Id$@uiD7@iqnDTaIo8+
zyV>(n7Ls@DKFB<FqO7V-
xpu@iN36HTd@g76i6Zb~*Ok7Rt*dfT7boHmyUtp=;i;K(
zo^g-
W@FnOXzE@lLs*zExG5O1n$4E0i3Vj`1la=w~d*Rw6t)*%#8qJA``utI=&gXax
z|FhF$H#bn-d!tC;obk9gsE#aZW7`pd*NC^C^!K$wv6t-H-o^KX5&g~k(7qbL-
AH!%
z2@qzF6)k>Vp2}uwYkVd1H)P>oTCvDQf3r9rtC-
mFvyX}sR8P6g7q^*ax)F|8UHrt%
QHyJ;b`f6NX>FQbZ9}*T`00000
literal 0 HcmV?d00001
diff --git a/Platforms/Marvell/Marvell.dec
b/Platforms/Marvell/Marvell.dec
index e63add4..f9d2660 100644 --- a/Platforms/Marvell/Marvell.dec +++ b/Platforms/Marvell/Marvell.dec @@ -54,6 +54,7 @@
gShellEepromHiiGuid = { 0xb2f4c714, 0x147f, 0x4ff7, { 0x82, 0x1b, 0xce,
0x7b, 0x91, 0x7f, 0x5f, 0x2f } }
gShellSfHiiGuid = { 0x03a67756, 0x8cde, 0x4638, { 0x82, 0x34, 0x4a, 0x0f,
0x6d, 0x58, 0x81, 0x39 } }
- gShellFUpdateHiiGuid = { 0x9b5d2176, 0x590a, 0x49db, { 0x89, 0x5d,
0x4a, 0x70, 0xfe, 0xad, 0xbe, 0x24 } }
[PcdsFixedAtBuild.common]
#MPP
1.8.3.1
Leif,
I agree on EBL, but I have very little experience with EBL so I don’t want to discuss in detail as I am not the right person without more research. Specifically, my gut reaction is that needing a platform specific boot loader indicates that something has already gone wrong on that platform.
However, this does not seem like a boot loader or an application at all. this is an internal shell command. The goal here seems to be to create a NULL library to add a new internal command to the UEFI Shell. This library gets compiled/linked into the shell itself.
I feel that we have found a "new" use case that I encountered, but worked around in the past because all previous cases involved commands in the same library (there are interactions between Reconnect and Disconnect/Connect).
I would say that a new API in the ShellCommandLib that links the UEFI Shell Application to the NULL libraries that make up the internal commands would be my first choice for implementation. I would lean to something like the function that Marcin already called. Maybe this?
EFIAPI RunRegisteredCommand( CHAR16* CommandLine, EFI_STATUS *CommandReturnValue )
-Jaben
-----Original Message----- From: Leif Lindholm [mailto:leif.lindholm@linaro.org] Sent: Wednesday, November 16, 2016 9:36 AM To: Carsey, Jaben jaben.carsey@intel.com Cc: Marcin Wojtas mw@semihalf.com; Ard Biesheuvel ard.biesheuvel@linaro.org; linaro-uefi linaro-uefi@lists.linaro.org; Neta Zur Hershkovits neta@marvell.com; Yehuda Yitschak yehuday@marvell.com; Haim Boot hayim@marvell.com; Jan Dabros jsd@semihalf.com; Bartosz Szczepanek bsz@semihalf.com; edk2-devel- 01 edk2-devel@lists.01.org; Ni, Ruiyu ruiyu.ni@intel.com Subject: Re: [PATCH v6 21/23] Applications/FirmwareUpdate: Add 'fupdate' comand to shell Importance: High
Hi Jaben,
I've seen a few different solutions to the same problem of providing platform-specific "shorthand" commands, my least favourite one being embedding a locally hacked EBL.
I guess we're ending up with something halfway between an application and a script.
Is it your view that this should always be implemented as a standalone application, to be called from the UI config menus?
Basically, is there an expected usage pattern that people keep missing?
Regards,
Leif
On Wed, Nov 16, 2016 at 05:05:36PM +0000, Carsey, Jaben wrote:
Marcin and Ard,
It sounds like there is a goal to have a UEFI Application call into an internal
shell command.
There is no documented method to programmatically call an internal command. This is not a goal of the current shell implementation. ShellExecute explicitly does not allow running of internal commands (per UEFI Shell Specification 2.2).
Thus I don’t think using ShellDynamicCommandProtocol will help. That protocol is for allowing a driver add a command to the shell's list of available commands.
-Jaben
-----Original Message----- From: Marcin Wojtas [mailto:mw@semihalf.com] Sent: Wednesday, November 16, 2016 8:13 AM To: Ard Biesheuvel ard.biesheuvel@linaro.org Cc: linaro-uefi linaro-uefi@lists.linaro.org; Leif Lindholm leif.lindholm@linaro.org; Neta Zur Hershkovits neta@marvell.com; Yehuda Yitschak yehuday@marvell.com; Haim Boot hayim@marvell.com; Jan Dąbroś jsd@semihalf.com; Bartosz Szczepanek bsz@semihalf.com; edk2-devel-01 <edk2-
devel@lists.01.org>;
Carsey, Jaben jaben.carsey@intel.com; Ni, Ruiyu ruiyu.ni@intel.com Subject: Re: [PATCH v6 21/23] Applications/FirmwareUpdate: Add
'fupdate'
comand to shell Importance: High
- Jaben, Ruiyu and edk2 list
Hi Ard,
Internal Shell header ("../../../ShellPkg/Application/Shell/Shell.h") was added ONLY for being able to execute shell commands (tftp and our custom SPI flash control) from within a new command. This is now done with: RunShellCommand (TftpCmd, &Status); And it works fine.
Replacing above with: ShellExecute (&ImageHandle, TftpCmd, FALSE, NULL, &Status); allow to get rid of relative include and seems more appropriate, but there is completely no effect of calling it.
I checked in edk2 sources and see no relation between above problem and registering our command with help of ShellDynamicCommand
protocol.
Unless I don't know something. Anyway, I'll apreciate any hint, how to solve the issue in a nice way.
Best regards, Marcin
2016-11-15 17:09 GMT+01:00 Ard Biesheuvel
On 10 July 2016 at 00:21, Marcin Wojtas mw@semihalf.com wrote:
From: Jan Dąbroś jsd@semihalf.com
'fupdate' command performs updating firmware from file placed on
local
filesystem or on TFTP server. It uses tftp and sf commands.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jan Dabros jsd@semihalf.com Signed-off-by: Marcin Wojtas mw@semihalf.com
Please use the Shell dynamic command protocol to add commands to
the
shell. This will remove the need for including internal Shell headers, and even allow your commands to work with prebuilt Shell binaries.
MdePkg/Include/Protocol/ShellDynamicCommand.h
Thanks, Ard.
Applications/FirmwareUpdate/FUpdate.c | 448
++++++++++++++++++++++++++++++++
Applications/FirmwareUpdate/FUpdate.inf | 68 +++++ Applications/FirmwareUpdate/FUpdate.uni | Bin 0 -> 5838 bytes Platforms/Marvell/Marvell.dec | 1 + 4 files changed, 517 insertions(+) create mode 100644 Applications/FirmwareUpdate/FUpdate.c create mode 100644 Applications/FirmwareUpdate/FUpdate.inf create mode 100644 Applications/FirmwareUpdate/FUpdate.uni
diff --git a/Applications/FirmwareUpdate/FUpdate.c
b/Applications/FirmwareUpdate/FUpdate.c
new file mode 100644 index 0000000..359a4ac --- /dev/null +++ b/Applications/FirmwareUpdate/FUpdate.c @@ -0,0 +1,448 @@
+/*********************************************************
+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/DebugLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/ShellCommandLib.h> +#include <Library/ShellLib.h> +#include <Library/UefiLib.h> +#include <Library/PrintLib.h> +#include <Library/UefiLib.h> +#include <Library/ShellCEntryLib.h> +#include <Library/HiiLib.h> +#include <Guid/ShellLibHiiGuid.h> +#include <Library/UefiBootServicesTableLib.h> +#include <Library/FileHandleLib.h> +// FIXME: Remove including relative path +#include "../../../ShellPkg/Application/Shell/Shell.h"
+#define CMD_NAME_STRING L"fupdate"
+#define TFTP_CMD_STRING L"tftp " +#define SPACE_STRING L" " +#define SF_PROBE_CMD_STRING L"sf probe" +#define SF_WRITE_CMD_STRING L"sf updatefile " +#define SF_LOAD_ADDR_STRING L"0x0"
+#define MAIN_HDR_MAGIC 0xB105B002
+typedef struct {
- 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_IMAGE_HEADER;
+STATIC +UINT32 +CountChecksum (
- UINT32 *Start,
- UINT32 Length
- )
+{
- UINT32 Sum = 0;
- UINT32 *Startp = Start;
- do {
- Sum += *Startp;
- Startp++;
- Length -= 4;
- } while (Length > 0);
- return Sum;
+}
+STATIC +EFI_STATUS +CheckImageHeader (
- IN VOID *ImageHeader
- )
+{
- MV_IMAGE_HEADER *Header;
- UINT32 HeaderLength, Checksum, ChecksumBackup;
- Header = (MV_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 = CountChecksum((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 +CheckFirmwareImage (
- CONST CHAR16* FirmwareImage
- )
+{
- EFI_STATUS Status;
- VOID *FileBuffer;
- UINT64 OpenMode;
- UINTN FileSize;
- SHELL_FILE_HANDLE FileHandle = NULL;
- OpenMode = EFI_FILE_MODE_READ;
- Status = ShellOpenFileByName (FirmwareImage, &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);
- }
- FileBuffer = AllocateZeroPool (FileSize);
- // Read Image header into buffer
- Status = FileHandleRead (FileHandle, &FileSize, FileBuffer);
- if (EFI_ERROR (Status)) {
Print (L"%s: Cannot read Image file header\n",
CMD_NAME_STRING);
ShellCloseFile (&FileHandle);
FreePool (FileBuffer);
return EFI_DEVICE_ERROR;
- }
- Status = CheckImageHeader (FileBuffer);
- if (EFI_ERROR(Status)) {
- return EFI_DEVICE_ERROR;
- }
- FreePool (FileBuffer);
- return EFI_SUCCESS;
+}
+STATIC +CONST CHAR16 * +FileNameFromFilePath (
- CONST CHAR16 *RemoteFilePath
- )
+{
- CONST CHAR16 *Walker;
- // Gather FileName from FilePath
- Walker = RemoteFilePath + StrLen (RemoteFilePath);
- while ((--Walker) >= RemoteFilePath) {
- if ((*Walker == L'\') || (*Walker == L'/')) {
break;
- }
- }
- return (Walker + 1);
+}
+STATIC +CONST CHAR16* +PrepareFile (
- LIST_ENTRY *CheckPackage
- )
+{
- EFI_STATUS Status;
- CONST CHAR16 *ValueStr;
- ValueStr = ShellCommandLineGetValue (CheckPackage, L"-f");
- if (ValueStr == NULL) {
- Print (L"%s: No LocalFilePath parameter!\n",
CMD_NAME_STRING);
- return NULL;
- } else {
- Status = ShellIsFile (ValueStr);
- if (EFI_ERROR(Status)) {
Print (L"%s: Wrong LocalFilePath parameter!\n",
CMD_NAME_STRING);
return NULL;
- }
- }
- return ValueStr;
+}
+CONST CHAR16 gShellFUpdateFileName[] = L"ShellCommand"; +EFI_HANDLE gShellFUpdateHiiHandle = NULL; +EFI_HANDLE gShellFUpdateHiiHandle;
+STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
- {L"help", TypeFlag},
- {L"-t", TypeFlag},
- {L"-f", TypeValue},
- {NULL , TypeMax}
- };
+/**
- Return the file name of the help text file if not using HII.
- @return The string pointer to the file name.
+**/ +CONST CHAR16* +EFIAPI +ShellCommandGetManFileNameFUpdate (
- VOID
- )
+{
- return gShellFUpdateFileName;
+}
+VOID +FUpdateUsage (
- VOID
- )
+{
- Print (L"\nFirmware update command\n"
"fupdate [-f <LocalFilePath>] [-t <Host>
<RemoteFilePath>]\n\n"
"LocalFilePath - path to local firmware image file\n"
"Host - IP number of TFTP server\n"
"RemoteFilePath - path to firmware image file on TFTP server\n"
"Examples:\n"
"Update firmware from file fs2:Uefi.img\n"
" fupdate -f fs2:Uefi.img\n"
"Update firmware from file path/Uefi.img TFTP server with IP "
"address 10.0.0.200\n"
" fupdate -t 10.0.0.200 path/Uefi.img\n"
- );
+}
+SHELL_STATUS +EFIAPI +ShellCommandRunFUpdate (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
+{
- EFI_STATUS Status;
- LIST_ENTRY *CheckPackage;
- CHAR16 *ProblemParam, *TftpCmd = NULL, *SfCmd = NULL;
- CONST CHAR16 *RemoteFilePath, *Host, *FileToWrite;
- UINT8 CmdLen;
- BOOLEAN FileFlag, TftpFlag;
- Status = ShellInitialize ();
- if (EFI_ERROR (Status)) {
- Print (L"%s: Error while initializinf Shell\n", CMD_NAME_STRING);
- ASSERT_EFI_ERROR (Status);
- return SHELL_ABORTED;
- }
- Status = ShellCommandLineParse (ParamList, &CheckPackage,
&ProblemParam,
- TRUE);
- if (EFI_ERROR (Status)) {
- Print (L"Parse error!\n");
- }
- if (ShellCommandLineGetFlag (CheckPackage, L"help")) {
- FUpdateUsage();
- return EFI_SUCCESS;
- }
- FileFlag = ShellCommandLineGetFlag (CheckPackage, L"-f");
- TftpFlag = ShellCommandLineGetFlag (CheckPackage, L"-t");
- if (!FileFlag && !TftpFlag) {
- Print (L"%s: Please specify -f or -t flag\n", CMD_NAME_STRING);
- return SHELL_ABORTED;
- } else if (FileFlag && !TftpFlag) {
- // Prepare local file to be burned into flash
- FileToWrite = PrepareFile (CheckPackage);
- if (FileToWrite == NULL) {
Print (L"%s: Error while preparing file for burn\n",
CMD_NAME_STRING);
return SHELL_ABORTED;
- }
- } else if (TftpFlag && !FileFlag) {
- Host = ShellCommandLineGetRawValue (CheckPackage, 1);
- if (Host == NULL) {
Print (L"%s: No Host parameter!\n", CMD_NAME_STRING);
return SHELL_ABORTED;
- }
- RemoteFilePath = ShellCommandLineGetRawValue
(CheckPackage, 2);
- if (RemoteFilePath == NULL) {
Print (L"%s: No remote_file_path parameter!\n",
CMD_NAME_STRING);
return SHELL_ABORTED;
- }
- // Gather firmware image name from remote filepath
- FileToWrite = FileNameFromFilePath (RemoteFilePath);
- // Allocate buffer for tftp command string
- CmdLen = StrSize (TFTP_CMD_STRING) + StrSize (SPACE_STRING)
StrSize (Host) + StrSize (RemoteFilePath);
- TftpCmd = (CHAR16 *) AllocateZeroPool (CmdLen +
sizeof(CHAR16));
- if (TftpCmd == NULL) {
Print (L"%s: Cannot allocate memory\n", CMD_NAME_STRING);
return SHELL_ABORTED;
- }
- // Concatenate parameters and form tftp command string
- StrCatS (TftpCmd, CmdLen / sizeof(CHAR16), TFTP_CMD_STRING);
- StrCatS (TftpCmd, CmdLen / sizeof(CHAR16), (CHAR16 *)Host);
- // Insert space
- StrCatS (TftpCmd, CmdLen / sizeof(CHAR16), SPACE_STRING);
- StrCatS (TftpCmd, CmdLen / sizeof(CHAR16), (CHAR16
*)RemoteFilePath);
- RunShellCommand (TftpCmd, &Status);
- FreePool (TftpCmd);
- if (EFI_ERROR(Status)) {
Print (L"%s: Error while performing tftp command\n",
CMD_NAME_STRING);
return SHELL_ABORTED;
- }
- } else {
- Print (L"%s: Both -f and -t flag specified, please choose one\n",
CMD_NAME_STRING);
- return SHELL_ABORTED;
- }
- // Check image checksum and magic
- Status = CheckFirmwareImage (FileToWrite);
- if (EFI_ERROR(Status)) {
- Print (L"%s: Wrong firmware Image\n", CMD_NAME_STRING);
- return SHELL_ABORTED;
- }
- // Probe spi bus
- RunShellCommand (SF_PROBE_CMD_STRING, &Status);
- if (EFI_ERROR(Status)) {
- Print (L"%s: Error while performing sf probe\n",
CMD_NAME_STRING);
- return SHELL_ABORTED;
- }
- // Allocate buffer for sf command string
- CmdLen = StrSize (SF_WRITE_CMD_STRING) + StrSize (FileToWrite)
- StrSize (SPACE_STRING) + StrSize (SF_LOAD_ADDR_STRING);
- SfCmd = (CHAR16 *) AllocateZeroPool (CmdLen + sizeof(CHAR16));
- if (SfCmd == NULL) {
- Print (L"%s: Cannot allocate memory\n");
- return SHELL_ABORTED;
- }
- // Concatenate parameters and form command string
- StrCatS (SfCmd, CmdLen / sizeof(CHAR16),
SF_WRITE_CMD_STRING);
- StrCatS (SfCmd, CmdLen / sizeof(CHAR16), (CHAR16 *)FileToWrite);
- StrCatS (SfCmd, CmdLen / sizeof(CHAR16), SPACE_STRING);
- StrCatS (SfCmd, CmdLen / sizeof(CHAR16),
SF_LOAD_ADDR_STRING);
- // Update firmware image in flash
- RunShellCommand (SfCmd, &Status);
- FreePool (SfCmd);
- if (EFI_ERROR(Status)) {
- Print (L"%s: Error while performing sf update\n",
CMD_NAME_STRING);
- return SHELL_ABORTED;
- }
- return EFI_SUCCESS;
+}
+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/Applications/FirmwareUpdate/FUpdate.inf
b/Applications/FirmwareUpdate/FUpdate.inf
new file mode 100644 index 0000000..53b5305 --- /dev/null +++ b/Applications/FirmwareUpdate/FUpdate.inf @@ -0,0 +1,68 @@ +# +# 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 = 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]
- 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
+[Guids]
- gShellFUpdateHiiGuid
diff --git a/Applications/FirmwareUpdate/FUpdate.uni
b/Applications/FirmwareUpdate/FUpdate.uni
new file mode 100644 index
0000000000000000000000000000000000000000..6143c0580f1d1ef8ce4fe619a1
df1ce380adf2c0
GIT binary patch literal 5838
zcmd6r?N1v=5XSd&rTz~m@+FOuK&z@BXdB5G6OhbHeI_(&s)*P?EX6>LDdL}
R`}}4Y
z_Fim)B2|h`_TBEy&OY<Z%kJL4|E#8GU-
k8E`X+VLMY>G4X_hAGEPYJ#RHUcs{Z98E
z(pvgH{iLVebS#O#(@FZIt4KTPT#_g1JJ*}J#$MPH@A_(w)60Z*e$BBPsZ5(DH%
TMu
zI8RslFVenngr*p~lTP*KR@$$1pGl4p6GJjq&s>Nn8egO>-
9MS0Q^{SVsru?OKUYs^
znhN!;+Src8b3GNB10={X)7Ui6^*l)*^bUIqjXT$yRmsoHx~ZO!JT-
lb@LbynxN^K`
zIn^kbyht}1doJb+wK5;k=NwOk%lRBE#O3S<wy>ix&4tFo-
prWGG9T<MUWEtn%*5H1
zSq~;Gfgeyu8$Ga<Z3c1n|8rvmo!EG(e{`Y?JMh~dM@OiCW&nJZN~Bn~_Gr
JG$Ij
zd>%7RrE8wn?<20zyXy5!t%sOH*M&t|ohxPqCl(VMpv1PhX2wGq^RXfXyO3p
6Go#Mc
z2Xdm<S*qfT=Nvu6g3sr;me~&{8O5Tg@+clDy1)!mvr2Bp%yEAVQ*Qa<_-
Qib{vL}x
zEYC<E=8NnPMAdtpMc3xp|Nrt8nS_5%EXt~=;(06|k7OwvQyp_&MAmuLAl6(
HxkV-N
zET8D<lf1qtOCkd^gYD|%d6DaG;EFrG-
4iy??Rq_;ii11ypk6r(+2fVKanpABoH=Nv
z<&j#gnvCR4)Z7mbaOf4-W15N#lkkcLM+avfRa7Cb$<-
)x6l5)Rn~X$TUK4VTk?W_@
za3fp1Vg<`y=axm`l~uNpw4drXy2AteUMrc`D;^ahSHUaU(DczTZEGzpC0A<w+
e*W9
zlsc+aJ@t71fm-|Njar-P-BkZZdaHj%BGuK~1N96f@mhUD^=+%KZ}J1v-
I3oJiR_*v
zkljd!dfL}Bv#)4Y?##KOyN`eYo|vzfe%Cx8D@~G-
$nUDRue)P&^aC3;wBFKIlpSg5
zO72iNcz$iYj)AD$H{9si)o*yG4ScM|VQYOh&@Gyeoy3+#?Mll)vu@v^>B#0C!#
XsJ
zf|V_saqr%;En@`^3fYD?u%s*OeQVKssNMs~l^TU4ynqMmO0%@1ClG9^+Q
QSG{;?A#
z-{^-
Q@H*)Fy0VpvJi0GSK?vv0{BmDzNRD0Djx=xRPRnho`V*v}?g|GSgK$w_S8s?s
z@PZWCQnoXa8N7$+=-
tHvY`itODpHvGO}x1#A6ZCqN25B52jU8RPYubJ$BO3*-oiRO
z;7of=l<H^yiARTeCejMczOQRj{lPA12bOhRJ(cNa!`7EnL_ZOBs8-
J`#SZv^9k<$X
zcx*8~`ic3{Y>Z5Td2kGL9g117k*Dmy$>bxwBVzD<S9AER<a0zY(pBGjzJP<wb;~
0j
zat46)NHg>_BmbVy#A%ML&V78q8Fhnr$<bBU=9YU^87}oEdC(K*Aj0od2E5>-
sRWMZ
zNblhn9*8MgUOOV6qBc<l+)_Lm7Dv@^zN)=wg0E)Hg^|ck=D^1t#Rb(DByjF*
hHkF`
z;HuY_9BtH}dYtDK`s+R&t{O-
1w3>cRPwrb!Y%j@~g;kdG85b+{3yV!w6Iy3>qPfzZ
zX{9ojT`eo5pLsm0-dh|D(|hxLUpeqz+>;BQS42nq$~dmIf}d&5CJLW-
MHLu-
u?x7?
zdOVi2?;F<Cx1yOQLNu-
H0}g9a>}aO8dtoo~QX}3;{+%qy`l;i@HPx)wdSBPauAx3(
z>^nf%KE)1&a40S~$+4?pPs1L58H!T5z)Evq`BJvzidIjPmp|l5{Q8S>lszr`Qdr`A
zePHZ;Os~?Pl0b59lG~ERx38?lX)E?;i$*TP4(h0Xk3mjUJT#X_%?n8_X0gin<(*~h
zvDtgF@4S(hIi(+~mG|D+OX0buJ?&^+)>Dm0=76ngbhQ19reJ%S)<S+^oo4sxJJ
nmY
zGY6%`kVg`g?m$uXqa?6%tocvmOTIZQvTJ!v1RCa!I0-
gk(Id$@uiD7@iqnDTaIo8+
zyV>(n7Ls@DKFB<FqO7V-
xpu@iN36HTd@g76i6Zb~*Ok7Rt*dfT7boHmyUtp=;i;K(
zo^g-
W@FnOXzE@lLs*zExG5O1n$4E0i3Vj`1la=w~d*Rw6t)*%#8qJA``utI=&gXax
z|FhF$H#bn-d!tC;obk9gsE#aZW7`pd*NC^C^!K$wv6t-H-
o^KX5&g~k(7qbL-
AH!%
z2@qzF6)k>Vp2}uwYkVd1H)P>oTCvDQf3r9rtC-
mFvyX}sR8P6g7q^*ax)F|8UHrt%
QHyJ;b`f6NX>FQbZ9}*T`00000
literal 0 HcmV?d00001
diff --git a/Platforms/Marvell/Marvell.dec
b/Platforms/Marvell/Marvell.dec
index e63add4..f9d2660 100644 --- a/Platforms/Marvell/Marvell.dec +++ b/Platforms/Marvell/Marvell.dec @@ -54,6 +54,7 @@
gShellEepromHiiGuid = { 0xb2f4c714, 0x147f, 0x4ff7, { 0x82, 0x1b,
0xce,
0x7b, 0x91, 0x7f, 0x5f, 0x2f } }
gShellSfHiiGuid = { 0x03a67756, 0x8cde, 0x4638, { 0x82, 0x34, 0x4a,
0x0f,
0x6d, 0x58, 0x81, 0x39 } }
- gShellFUpdateHiiGuid = { 0x9b5d2176, 0x590a, 0x49db, { 0x89, 0x5d,
0x4a, 0x70, 0xfe, 0xad, 0xbe, 0x24 } }
[PcdsFixedAtBuild.common]
#MPP
1.8.3.1
Hi Jaben,
Thank you for your input.
I agree on EBL, but I have very little experience with EBL so I don’t want to discuss in detail as I am not the right person without more research. Specifically, my gut reaction is that needing a platform specific boot loader indicates that something has already gone wrong on that platform.
However, this does not seem like a boot loader or an application at all. this is an internal shell command. The goal here seems to be to create a NULL library to add a new internal command to the UEFI Shell. This library gets compiled/linked into the shell itself.
Indeed, it's nothing similar to the bootloader whatsoever. This command simply enables updating firmware in SPI flash directly from local path or from tftp.
I feel that we have found a "new" use case that I encountered, but worked around in the past because all previous cases involved commands in the same library (there are interactions between Reconnect and Disconnect/Connect).
Right, however Reconnect is easy, as it simply calls gBS callbacks, whose definition are also in the same location.
I would say that a new API in the ShellCommandLib that links the UEFI Shell Application to the NULL libraries that make up the internal commands would be my first choice for implementation. I would lean to something like the function that Marcin already called. Maybe this?
EFIAPI RunRegisteredCommand( CHAR16* CommandLine, EFI_STATUS *CommandReturnValue )
I'll try this one and let know.
Thanks, Marcin
Hi Jaben,
I haven't found RunRegisteredCommand in newest edk2. Can you please point exactly what you meant?
As an alternative I checked ShellCommandRunCommandHandler - this is in fact a library helper function and it's nested deep down in RunShellCommand, which is for now the only working option. ShellCommandRunCommandHandler requires a lot of additional processing of the command line. All is done in Application/Shell code.
Is there any chance to expose RunShellCommand (or equivalent), so that it can be used in a nice way, not with including multi "../../" relative path header?
I expected, that the commands, which are in fact some wrappers or they mix multiple others is pretty much of a standard, I'm pretty surprised there are so huge difficulties in EDK2. I'm wondering of if there are any other options to be used here (unless we accept, what we have for now:) ).
Best regards, Marcin
2016-11-16 22:48 GMT+01:00 Marcin Wojtas mw@semihalf.com:
Hi Jaben,
Thank you for your input.
I agree on EBL, but I have very little experience with EBL so I don’t want to discuss in detail as I am not the right person without more research. Specifically, my gut reaction is that needing a platform specific boot loader indicates that something has already gone wrong on that platform.
However, this does not seem like a boot loader or an application at all. this is an internal shell command. The goal here seems to be to create a NULL library to add a new internal command to the UEFI Shell. This library gets compiled/linked into the shell itself.
Indeed, it's nothing similar to the bootloader whatsoever. This command simply enables updating firmware in SPI flash directly from local path or from tftp.
I feel that we have found a "new" use case that I encountered, but worked around in the past because all previous cases involved commands in the same library (there are interactions between Reconnect and Disconnect/Connect).
Right, however Reconnect is easy, as it simply calls gBS callbacks, whose definition are also in the same location.
I would say that a new API in the ShellCommandLib that links the UEFI Shell Application to the NULL libraries that make up the internal commands would be my first choice for implementation. I would lean to something like the function that Marcin already called. Maybe this?
EFIAPI RunRegisteredCommand( CHAR16* CommandLine, EFI_STATUS *CommandReturnValue )
I'll try this one and let know.
Thanks, Marcin
-----Original Message----- From: Marcin Wojtas [mailto:mw@semihalf.com] Sent: Wednesday, November 16, 2016 3:58 PM To: Carsey, Jaben jaben.carsey@intel.com Cc: Leif Lindholm leif.lindholm@linaro.org; Ard Biesheuvel ard.biesheuvel@linaro.org; linaro-uefi linaro-uefi@lists.linaro.org; Neta Zur Hershkovits neta@marvell.com; Yehuda Yitschak yehuday@marvell.com; Haim Boot hayim@marvell.com; Jan Dabros jsd@semihalf.com; Bartosz Szczepanek bsz@semihalf.com; edk2-devel-01 edk2-devel@lists.01.org; Ni, Ruiyu ruiyu.ni@intel.com Subject: Re: [PATCH v6 21/23] Applications/FirmwareUpdate: Add 'fupdate' comand to shell Importance: High
Hi Jaben,
I haven't found RunRegisteredCommand in newest edk2. Can you please point exactly what you meant?
I meant add a new function like that. It does not exist at all now.
As an alternative I checked ShellCommandRunCommandHandler - this is in fact a library helper function and it's nested deep down in RunShellCommand, which is for now the only working option. ShellCommandRunCommandHandler requires a lot of additional processing of the command line. All is done in Application/Shell code.
What's the difference that you need? I see this: looks like you would need a command line (which I assume you have), the return value (which I assume you want), and control over whether you want LastError changed based on this (I would suggest not, but...)
RETURN_STATUS EFIAPI ShellCommandRunCommandHandler ( IN CONST CHAR16 *CommandString, IN OUT SHELL_STATUS *RetVal, IN OUT BOOLEAN *CanAffectLE OPTIONAL )
The main difference between that and the RunShellCommand is things like file redirection, trimming space, alias replacement, and things that feel very "command-line" processing. I would think that your TFTP command line would be less needy of fixing up.
Is there any chance to expose RunShellCommand (or equivalent), so that it can be used in a nice way, not with including multi "../../" relative path header?
I expected, that the commands, which are in fact some wrappers or they mix multiple others is pretty much of a standard, I'm pretty surprised there are so huge difficulties in EDK2. I'm wondering of if there are any other options to be used here (unless we accept, what we have for now:) ).
I think we have less wrapping and less mixing that it appears at first. Those that are related are (I believe) in the same lib and as such, just call each other.
Best regards, Marcin
2016-11-16 22:48 GMT+01:00 Marcin Wojtas mw@semihalf.com:
Hi Jaben,
Thank you for your input.
I agree on EBL, but I have very little experience with EBL so I don’t want to
discuss in detail as I am not the right person without more research. Specifically, my gut reaction is that needing a platform specific boot loader indicates that something has already gone wrong on that platform.
However, this does not seem like a boot loader or an application at all. this is
an internal shell command. The goal here seems to be to create a NULL library to add a new internal command to the UEFI Shell. This library gets compiled/linked into the shell itself.
Indeed, it's nothing similar to the bootloader whatsoever. This command simply enables updating firmware in SPI flash directly from local path or from tftp.
I feel that we have found a "new" use case that I encountered, but worked
around in the past because all previous cases involved commands in the same library (there are interactions between Reconnect and Disconnect/Connect).
Right, however Reconnect is easy, as it simply calls gBS callbacks, whose definition are also in the same location.
I would say that a new API in the ShellCommandLib that links the UEFI Shell
Application to the NULL libraries that make up the internal commands would be my first choice for implementation. I would lean to something like the function that Marcin already called. Maybe this?
EFIAPI RunRegisteredCommand( CHAR16* CommandLine, EFI_STATUS *CommandReturnValue )
I'll try this one and let know.
Thanks, Marcin
From: Jan Dąbroś jsd@semihalf.com
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 --- Platforms/Marvell/Armada/Armada.dsc.inc | 1 + 1 file changed, 1 insertion(+)
diff --git a/Platforms/Marvell/Armada/Armada.dsc.inc b/Platforms/Marvell/Armada/Armada.dsc.inc index 0e234ef..5ef2098 100644 --- a/Platforms/Marvell/Armada/Armada.dsc.inc +++ b/Platforms/Marvell/Armada/Armada.dsc.inc @@ -437,6 +437,7 @@ NULL|ShellPkg/Library/UefiShellTftpCommandLib/UefiShellTftpCommandLib.inf NULL|OpenPlatformPkg/Applications/EepromCmd/EepromCmd.inf NULL|OpenPlatformPkg/Applications/SpiTool/SpiFlashCmd.inf + NULL|OpenPlatformPkg/Applications/FirmwareUpdate/FUpdate.inf HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.inf
From: Haim Boot hayim@marvell.com
The relocation type R_AARCH64_PREL32 in .rela.eh_frame (exception handling frame) does not fit the checking requirement of GenFw in EDK2.
Building EDK2 with aarch64-elf bare metal toolchain (no unwind table by default) will succeed. However build of EDK2 with aarch64-linux-gnueabi toolchain (default enable unwind table generation) will fail.
The issue can be fixed by adding -fno-unwind-tables, in order to disable generating unwind table info, which is used mainly for debug. This commit enables successful compilation of EDK2 both with aarch64-elf and aarch64-linux-gnueabi toolchains.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Haim Boot hayim@marvell.com Signed-off-by: Marcin Wojtas mw@semihalf.com --- Platforms/Marvell/Armada/Armada.dsc.inc | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/Platforms/Marvell/Armada/Armada.dsc.inc b/Platforms/Marvell/Armada/Armada.dsc.inc index 5ef2098..00e3c4d 100644 --- a/Platforms/Marvell/Armada/Armada.dsc.inc +++ b/Platforms/Marvell/Armada/Armada.dsc.inc @@ -197,6 +197,10 @@ # Add support for GCC stack protector NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
+ # Enable compilation with aarch64-linux-gnueabi toolchain +[BuildOptions] + *_*_*_PLATFORM_FLAGS = -fno-unwind-tables + ################################################################################ # # Pcd Section - list of all EDK II PCD Entries defined by this Platform
On 10 July 2016 at 02:21, Marcin Wojtas mw@semihalf.com wrote:
From: Haim Boot hayim@marvell.com
The relocation type R_AARCH64_PREL32 in .rela.eh_frame (exception handling frame) does not fit the checking requirement of GenFw in EDK2.
Building EDK2 with aarch64-elf bare metal toolchain (no unwind table by default) will succeed. However build of EDK2 with aarch64-linux-gnueabi toolchain (default enable unwind table generation) will fail.
EABI is closely tied to 32-bit ARM/AArch32, and so there is no such thing as a 'aarch64-linux-gnueabi' compiler.
The issue can be fixed by adding -fno-unwind-tables, in order to disable generating unwind table info, which is used mainly for debug. This commit enables successful compilation of EDK2 both with aarch64-elf and aarch64-linux-gnueabi toolchains.
This has nothing to do with bare metal vs hosted. Are you using the RedHat build of GCC by any chance?
Hi Ard,
2016-07-10 14:22 GMT+02:00 Ard Biesheuvel ard.biesheuvel@linaro.org:
On 10 July 2016 at 02:21, Marcin Wojtas mw@semihalf.com wrote:
From: Haim Boot hayim@marvell.com
The relocation type R_AARCH64_PREL32 in .rela.eh_frame (exception handling frame) does not fit the checking requirement of GenFw in EDK2.
Building EDK2 with aarch64-elf bare metal toolchain (no unwind table by default) will succeed. However build of EDK2 with aarch64-linux-gnueabi toolchain (default enable unwind table generation) will fail.
EABI is closely tied to 32-bit ARM/AArch32, and so there is no such thing as a 'aarch64-linux-gnueabi' compiler.
You are right, I checked, and the compiler in question is in fact aarch64-marvell-linux-gnu-
The issue can be fixed by adding -fno-unwind-tables, in order to disable generating unwind table info, which is used mainly for debug. This commit enables successful compilation of EDK2 both with aarch64-elf and aarch64-linux-gnueabi toolchains.
This has nothing to do with bare metal vs hosted. Are you using the RedHat build of GCC by any chance?
No, it's Marvell GCC toolchain. Do you have more remarks apart from s/gnueabi/gnu? I can ask Marvell to answer them, however I'd like to know your opinion if we can give a chance for such patch at all or it's a hopeless effort from the very beginning.
Best regards, Marcin
On 10 July 2016 at 20:45, Marcin Wojtas mw@semihalf.com wrote:
Hi Ard,
2016-07-10 14:22 GMT+02:00 Ard Biesheuvel ard.biesheuvel@linaro.org:
On 10 July 2016 at 02:21, Marcin Wojtas mw@semihalf.com wrote:
From: Haim Boot hayim@marvell.com
The relocation type R_AARCH64_PREL32 in .rela.eh_frame (exception handling frame) does not fit the checking requirement of GenFw in EDK2.
Building EDK2 with aarch64-elf bare metal toolchain (no unwind table by default) will succeed. However build of EDK2 with aarch64-linux-gnueabi toolchain (default enable unwind table generation) will fail.
EABI is closely tied to 32-bit ARM/AArch32, and so there is no such thing as a 'aarch64-linux-gnueabi' compiler.
You are right, I checked, and the compiler in question is in fact aarch64-marvell-linux-gnu-
The issue can be fixed by adding -fno-unwind-tables, in order to disable generating unwind table info, which is used mainly for debug. This commit enables successful compilation of EDK2 both with aarch64-elf and aarch64-linux-gnueabi toolchains.
This has nothing to do with bare metal vs hosted. Are you using the RedHat build of GCC by any chance?
No, it's Marvell GCC toolchain. Do you have more remarks apart from s/gnueabi/gnu? I can ask Marvell to answer them, however I'd like to know your opinion if we can give a chance for such patch at all or it's a hopeless effort from the very beginning.
We already fixed a similar issue in EDK2 commit 28e80befa4fe0ed:
""" BaseTools: aarch64: add -fno-asynchronous-unwind-tables to gcc cflags
Some toolchains, at least Fedora GCC, generate inline unwind tables in object files. These confuses GenFw to no end, leading to build failures: GenFw: ERROR 3000: Invalid WriteSections64(): ... unsupported ELF EM_AARCH64 relocation 0x105. GenFw: ERROR 3000: Invalid WriteSections64(): ... unsupported ELF EM_AARCH64 relocation 0x0.
I am aware of no current use of these tables, so explicitly disable their generation for aarch64.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Leif Lindholm leif.lindholm@linaro.org Tested-by: Wei Huang wei@redhat.com Reviewed-by: Olivier Martin olivier.martin@arm.com """
Note that ELF_EM_AARCH64 0x105 is the R_AARCH64_PREL32 you mention as well.
Since this setting is now applied globally, could you please check first if you still need this flag in the first place? Disabling unwind table generation altogether may affect debug capability, so it is better to keep the tables, but put them in a debug section (please refer to 26ecc55c027d77 for more details)
Thanks, Ard.
Hi Ard,
Thank you for pointing the patch!
I checked gcc-linaro-5.3-2016.02-x86_64_aarch64-linux-gnu compiler and indeed -fno-asynchronous-unwind-tables are enough to compile succesfully. Marvell gcc still has GenFW problems though: http://pastebin.com/KyYKj00D
Regardless of that, let's drop this patch for now. Since almost entire patchset is acked, I certainly don't want to block it with this issue.
Best regards, Marcin
2016-07-11 9:51 GMT+02:00 Ard Biesheuvel ard.biesheuvel@linaro.org:
On 10 July 2016 at 20:45, Marcin Wojtas mw@semihalf.com wrote:
Hi Ard,
2016-07-10 14:22 GMT+02:00 Ard Biesheuvel ard.biesheuvel@linaro.org:
On 10 July 2016 at 02:21, Marcin Wojtas mw@semihalf.com wrote:
From: Haim Boot hayim@marvell.com
The relocation type R_AARCH64_PREL32 in .rela.eh_frame (exception handling frame) does not fit the checking requirement of GenFw in EDK2.
Building EDK2 with aarch64-elf bare metal toolchain (no unwind table by default) will succeed. However build of EDK2 with aarch64-linux-gnueabi toolchain (default enable unwind table generation) will fail.
EABI is closely tied to 32-bit ARM/AArch32, and so there is no such thing as a 'aarch64-linux-gnueabi' compiler.
You are right, I checked, and the compiler in question is in fact aarch64-marvell-linux-gnu-
The issue can be fixed by adding -fno-unwind-tables, in order to disable generating unwind table info, which is used mainly for debug. This commit enables successful compilation of EDK2 both with aarch64-elf and aarch64-linux-gnueabi toolchains.
This has nothing to do with bare metal vs hosted. Are you using the RedHat build of GCC by any chance?
No, it's Marvell GCC toolchain. Do you have more remarks apart from s/gnueabi/gnu? I can ask Marvell to answer them, however I'd like to know your opinion if we can give a chance for such patch at all or it's a hopeless effort from the very beginning.
We already fixed a similar issue in EDK2 commit 28e80befa4fe0ed:
""" BaseTools: aarch64: add -fno-asynchronous-unwind-tables to gcc cflags
Some toolchains, at least Fedora GCC, generate inline unwind tables in object files. These confuses GenFw to no end, leading to build failures: GenFw: ERROR 3000: Invalid WriteSections64(): ... unsupported ELF EM_AARCH64 relocation 0x105. GenFw: ERROR 3000: Invalid WriteSections64(): ... unsupported ELF EM_AARCH64 relocation 0x0.
I am aware of no current use of these tables, so explicitly disable their generation for aarch64.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Leif Lindholm leif.lindholm@linaro.org Tested-by: Wei Huang wei@redhat.com Reviewed-by: Olivier Martin olivier.martin@arm.com """
Note that ELF_EM_AARCH64 0x105 is the R_AARCH64_PREL32 you mention as well.
Since this setting is now applied globally, could you please check first if you still need this flag in the first place? Disabling unwind table generation altogether may affect debug capability, so it is better to keep the tables, but put them in a debug section (please refer to 26ecc55c027d77 for more details)
Thanks, Ard.
On 11 July 2016 at 12:02, Marcin Wojtas mw@semihalf.com wrote:
Hi Ard,
Thank you for pointing the patch!
I checked gcc-linaro-5.3-2016.02-x86_64_aarch64-linux-gnu compiler and indeed -fno-asynchronous-unwind-tables are enough to compile succesfully. Marvell gcc still has GenFW problems though: http://pastebin.com/KyYKj00D
Could you also pastebin the output of
readelf -a /home/mw/git/edk2/Build/Armada70x0/RELEASE_GCC49/AARCH64/ArmPlatformPkg/PrePi/PeiMPCore/DEBUG/ArmPlatformPrePiMPCore.dll
and the contents of
/home/mw/git/edk2/Build/Armada70x0/RELEASE_GCC49/AARCH64/ArmPlatformPkg/PrePi/PeiMPCore/DEBUG/ArmPlatformPrePiMPCore.map
please?
Regardless of that, let's drop this patch for now. Since almost entire patchset is acked, I certainly don't want to block it with this issue.
Indeed. the ELF to PE/COFF conversion is a horrible hack, and quite a lot of effort goes into keeping it working with the various code models that GCC provides for AArch64. Adding vendor builds to the mix is going to make this even more complicated so I don't intend to dig too deep here. But I'd still like to understand what is going on.
Any reason you need to use the Marvell build rather than e.g., a Linaro build or distro build?
Hi Ard,
2016-07-11 12:09 GMT+02:00 Ard Biesheuvel ard.biesheuvel@linaro.org:
On 11 July 2016 at 12:02, Marcin Wojtas mw@semihalf.com wrote:
Hi Ard,
Thank you for pointing the patch!
I checked gcc-linaro-5.3-2016.02-x86_64_aarch64-linux-gnu compiler and indeed -fno-asynchronous-unwind-tables are enough to compile succesfully. Marvell gcc still has GenFW problems though: http://pastebin.com/KyYKj00D
Could you also pastebin the output of
readelf -a /home/mw/git/edk2/Build/Armada70x0/RELEASE_GCC49/AARCH64/ArmPlatformPkg/PrePi/PeiMPCore/DEBUG/ArmPlatformPrePiMPCore.dll
Readelf output is too big for pastebin, so I attach it.
and the contents of
/home/mw/git/edk2/Build/Armada70x0/RELEASE_GCC49/AARCH64/ArmPlatformPkg/PrePi/PeiMPCore/DEBUG/ArmPlatformPrePiMPCore.map
Indeed. the ELF to PE/COFF conversion is a horrible hack, and quite a lot of effort goes into keeping it working with the various code models that GCC provides for AArch64. Adding vendor builds to the mix is going to make this even more complicated so I don't intend to dig too deep here. But I'd still like to understand what is going on.
Any reason you need to use the Marvell build rather than e.g., a Linaro build or distro build?
I guess it is a wish of Marvell to compile all their stuff (u-boot, linux, atf, buildroot, edk2...) with their common toolchain.
Best regards, Marcin
On 11 July 2016 at 13:41, Marcin Wojtas mw@semihalf.com wrote:
Hi Ard,
2016-07-11 12:09 GMT+02:00 Ard Biesheuvel ard.biesheuvel@linaro.org:
On 11 July 2016 at 12:02, Marcin Wojtas mw@semihalf.com wrote:
Hi Ard,
Thank you for pointing the patch!
I checked gcc-linaro-5.3-2016.02-x86_64_aarch64-linux-gnu compiler and indeed -fno-asynchronous-unwind-tables are enough to compile succesfully. Marvell gcc still has GenFW problems though: http://pastebin.com/KyYKj00D
Could you also pastebin the output of
readelf -a /home/mw/git/edk2/Build/Armada70x0/RELEASE_GCC49/AARCH64/ArmPlatformPkg/PrePi/PeiMPCore/DEBUG/ArmPlatformPrePiMPCore.dll
Readelf output is too big for pastebin, so I attach it.
Is this with -fno-asynchronous-unwind-tables? I still see a .eh_frame section in the .dll
and the contents of
/home/mw/git/edk2/Build/Armada70x0/RELEASE_GCC49/AARCH64/ArmPlatformPkg/PrePi/PeiMPCore/DEBUG/ArmPlatformPrePiMPCore.map
Indeed. the ELF to PE/COFF conversion is a horrible hack, and quite a lot of effort goes into keeping it working with the various code models that GCC provides for AArch64. Adding vendor builds to the mix is going to make this even more complicated so I don't intend to dig too deep here. But I'd still like to understand what is going on.
Any reason you need to use the Marvell build rather than e.g., a Linaro build or distro build?
I guess it is a wish of Marvell to compile all their stuff (u-boot, linux, atf, buildroot, edk2...) with their common toolchain.
Best regards, Marcin
2016-07-11 13:45 GMT+02:00 Ard Biesheuvel ard.biesheuvel@linaro.org:
On 11 July 2016 at 13:41, Marcin Wojtas mw@semihalf.com wrote:
Hi Ard,
2016-07-11 12:09 GMT+02:00 Ard Biesheuvel ard.biesheuvel@linaro.org:
On 11 July 2016 at 12:02, Marcin Wojtas mw@semihalf.com wrote:
Hi Ard,
Thank you for pointing the patch!
I checked gcc-linaro-5.3-2016.02-x86_64_aarch64-linux-gnu compiler and indeed -fno-asynchronous-unwind-tables are enough to compile succesfully. Marvell gcc still has GenFW problems though: http://pastebin.com/KyYKj00D
Could you also pastebin the output of
readelf -a /home/mw/git/edk2/Build/Armada70x0/RELEASE_GCC49/AARCH64/ArmPlatformPkg/PrePi/PeiMPCore/DEBUG/ArmPlatformPrePiMPCore.dll
Readelf output is too big for pastebin, so I attach it.
Is this with -fno-asynchronous-unwind-tables? I still see a .eh_frame section in the .dll
No idea, why is that, but as you may see in http://pastebin.com/KyYKj00D -fno-asynchronous-unwind-tables is set during compilation - see log right above GenFW problem.
Best regards, Marcin
On 11 July 2016 at 14:04, Marcin Wojtas mw@semihalf.com wrote:
2016-07-11 13:45 GMT+02:00 Ard Biesheuvel ard.biesheuvel@linaro.org:
On 11 July 2016 at 13:41, Marcin Wojtas mw@semihalf.com wrote:
Hi Ard,
2016-07-11 12:09 GMT+02:00 Ard Biesheuvel ard.biesheuvel@linaro.org:
On 11 July 2016 at 12:02, Marcin Wojtas mw@semihalf.com wrote:
Hi Ard,
Thank you for pointing the patch!
I checked gcc-linaro-5.3-2016.02-x86_64_aarch64-linux-gnu compiler and indeed -fno-asynchronous-unwind-tables are enough to compile succesfully. Marvell gcc still has GenFW problems though: http://pastebin.com/KyYKj00D
Could you also pastebin the output of
readelf -a /home/mw/git/edk2/Build/Armada70x0/RELEASE_GCC49/AARCH64/ArmPlatformPkg/PrePi/PeiMPCore/DEBUG/ArmPlatformPrePiMPCore.dll
Readelf output is too big for pastebin, so I attach it.
Is this with -fno-asynchronous-unwind-tables? I still see a .eh_frame section in the .dll
No idea, why is that, but as you may see in http://pastebin.com/KyYKj00D -fno-asynchronous-unwind-tables is set during compilation - see log right above GenFW problem.
OK, thanks for confirming.
I don't see any solution to this other than reporting it to Marvell, and asking them to fix their toolchain. We have good reasons to omit .eh_frame sections from the build, since they use up space for no benefit (we don't use it at runtime, only when debugging, and GDB can fetch the .debug_frame section straight from the .dll)
Regards, Ard.
2016-07-11 14:52 GMT+02:00 Ard Biesheuvel ard.biesheuvel@linaro.org:
On 11 July 2016 at 14:04, Marcin Wojtas mw@semihalf.com wrote:
2016-07-11 13:45 GMT+02:00 Ard Biesheuvel ard.biesheuvel@linaro.org:
On 11 July 2016 at 13:41, Marcin Wojtas mw@semihalf.com wrote:
Hi Ard,
2016-07-11 12:09 GMT+02:00 Ard Biesheuvel ard.biesheuvel@linaro.org:
On 11 July 2016 at 12:02, Marcin Wojtas mw@semihalf.com wrote:
Hi Ard,
Thank you for pointing the patch!
I checked gcc-linaro-5.3-2016.02-x86_64_aarch64-linux-gnu compiler and indeed -fno-asynchronous-unwind-tables are enough to compile succesfully. Marvell gcc still has GenFW problems though: http://pastebin.com/KyYKj00D
Could you also pastebin the output of
readelf -a /home/mw/git/edk2/Build/Armada70x0/RELEASE_GCC49/AARCH64/ArmPlatformPkg/PrePi/PeiMPCore/DEBUG/ArmPlatformPrePiMPCore.dll
Readelf output is too big for pastebin, so I attach it.
Is this with -fno-asynchronous-unwind-tables? I still see a .eh_frame section in the .dll
No idea, why is that, but as you may see in http://pastebin.com/KyYKj00D -fno-asynchronous-unwind-tables is set during compilation - see log right above GenFW problem.
OK, thanks for confirming.
I don't see any solution to this other than reporting it to Marvell, and asking them to fix their toolchain. We have good reasons to omit .eh_frame sections from the build, since they use up space for no benefit (we don't use it at runtime, only when debugging, and GDB can fetch the .debug_frame section straight from the .dll)
This is what I've done. Thank you for your help.
Best regards, Marcin
On Sun, Jul 10, 2016 at 02:21:24AM +0200, Marcin Wojtas wrote:
Hello,
Here's 6th version of the support. It's rebased on top of newest master branch and comprise fixes from the latest review.
Patches are also available in the github: https://github.com/MarvellEmbeddedProcessors/edk2-open-platform/commits/opp-...
Any comments or remarks would be welcome.
Hi Marcin. I have now pushed 1-20/23 to OpenPlatformPkg master. 21-22, I still want to give some more thought, and 23 we've agreed to drop.
Many thanks for your contribution.
Regards,
Leif
Best regards, Marcin
Changelog: v5 -> v6
- Initial support
- Enable compilation after ArmMmuLib was added to edk2
- Remove commented-out line
- Enable up to 64MB RamDisk space for all Armada platforms
- Move adding "-fno-unwind-tables" build flag to a separate patch and add explanation for this change
- I2C
- Change MvI2cDevicePathProtocol to STATIC in MvI2cDxe.c
- Generate new I2C_GUID
- Move I2C_GUID to header files and extend existing FIXME comment
- Fupdate
- Add FIXME note over including relative path from edk2. It was needed after fixing regression by replacing ShellExecute with RunShellCommand
v4 -> v5
- Add ParsePcdLib
- Library created in order to parse PCD strings - it makes support for multi-controller easier to implement
- I2c
- Introduce multi-bus support
- Remove comments regarding GUID-slave address dependency
- Add FIXME comment about no-restart dual definition
- eeprom command
- Enable selecting I2C bus
- Add FIXME comment about no-restart dual definition
- Spi
- Fix writing procedure
- Rename protocol to MARVELL_SPI_MASTER_PROTOCOL
- General
- Remove commented-out, unused lines
v3 -> v4
- Update license messages
- Unify
- Add "Based on" statement were needed
- Wrap every message at 80 characters
- Add Marvell copyrights
- Fix namings
- All protocol/file names updated as suggested in review
- Clean-up
- Remove unneded blank lines and spaces
- Fix typos
- Add "Reviewed by" for currently accepted patches
- Add support for new platform - Armada70x0
- Remove support for old platforms Apn806 and Armada7040_rz
- Armada70x0 is based on Armada7040_rz with silicone fixes and improvements
- No changes on drivers/libraries caused by this change
- Update commit logs in whole tree
- MppLib
- Fix issue with writing to uninitialized memory
- I2c and eeprom command
- Remove dependency on BdsLibConnectAll call
- I2c stack is connected only if eeprom command is executed and only in case it wasn't done before
- gBS->ConnectController() used
- BdsLib
- Remove import of BdsLib
- After rebase on top of new edk2, extra BdsLibConnectAll call isn't necessary (actually for now no BdsLibConnectAll is needed at all for our platform support)
- sf command
- Remove inclusion of relative path
- Necessary macro now defined in globally exported file
- RamDisk driver
- Drop patch with this feature
- As long as there is no possibility to format RamDisk with FAT, driver is not useful on Armada70x0
- fupdate command
- Fix issue with "bad checksum"
v2 -> v3
- Decrease binary size
- Fupdate command
- Remove regression - replace ShellExecute with RunShellCommand
- Improve error paths
- Add proper DEBUG library and change error print levels
v1 -> v2
- Fix "may be used uninitialized" variables issue, branch compiles both with DEBUG and RELEASE flags
- Remove I2C_FLAG_NORESTART dependency - replace it with local definition
- Remove Marvell UART Library:
Since in edk2 there is support for 16550, internal library is unnecessary.
- DW8250 IP has programming interface compatible with NS-16550.
- /Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf is used instead
- RamDisk driver:
- Remove old driver imported from EFI TOOLKIT 2.0
- Replace it with new MdeModulePkg/Universal/Disk/RamDiskDxe from edk2
- Lack of FAT formatting issue emerged
- Add explicit dependency on IoLib in Drivers/Spi/SpiDxe.inf
- Add poster's "Signed-off-by" registry to every commit message
- Move to 05.04.2016 HEAD of edk2/master
- Update CpuExceptionHandlerLib within OPP.
Bartosz Szczepanek (3): Drivers/I2c: Create MvI2cDxe driver Drivers/I2c: Add MvEeprom driver Aplications/Eeprom: Add 'eeprom' command to shell
Haim Boot (1): Platforms/Marvell: Enable compilation with aarch64-linux-gnueabi toolchain
Jan Dąbroś (17): Platforms/Marvell: Create MppLib Platforms/Marvell: Armada: Enable MppLib on Armada70x0 platform Platforms/Marvell: Create ParsePcdLib Platforms/Marvell: Enable ParsePcdLib for Armada70x0 platform Platforms/Marvell: Enable I2C driver on Armada70x0 platform Plaforms/Marvell: Enable EEPROM driver on Armada70x0 platform Platforms/Marvell: Enable 'eeprom' command on Armada70x0 platform Platforms/Marvell: Add MARVELL_SPI_MASTER_PROTOCOL Drivers/Spi: Add Spi master driver Platforms/Marvell: Enable Spi master driver for Armada70x0 platform Platforms/Marvell: Add MARVELL_SPI_FLASH_PROTOCOL Drivers/Spi: Implement Spi flash driver Platforms/Marvell: Enable Spi flash driver for Armada70x0 platform Applications/SpiTool: Add 'sf' command utility Platforms/Marvell: Enable 'sf' command on Armada70x0 platform Applications/FirmwareUpdate: Add 'fupdate' comand to shell Platforms/Marvell: Enable 'fupdate' command on Armada70x0 platform
Yehuda Yitschak (2): Platforms/Marvell: Add initial support for Armada70x0 SOC lib Platforms/Marvell: Add support for Armada70x0 platform
Applications/EepromCmd/EepromCmd.c | 397 +++++++++++ Applications/EepromCmd/EepromCmd.inf | 71 ++ Applications/EepromCmd/EepromCmd.uni | Bin 0 -> 6816 bytes Applications/FirmwareUpdate/FUpdate.c | 448 +++++++++++++ Applications/FirmwareUpdate/FUpdate.inf | 68 ++ Applications/FirmwareUpdate/FUpdate.uni | Bin 0 -> 5838 bytes Applications/SpiTool/SpiFlashCmd.c | 526 +++++++++++++++ Applications/SpiTool/SpiFlashCmd.inf | 75 +++ Applications/SpiTool/SpiFlashCmd.uni | Bin 0 -> 7216 bytes Documentation/Marvell/Drivers/EepromDriver.txt | 96 +++ Documentation/Marvell/Drivers/I2cDriver.txt | 64 ++ Documentation/Marvell/Drivers/SpiDriver.txt | 116 ++++ Documentation/Marvell/PortingGuide/I2c.txt | 20 + Documentation/Marvell/PortingGuide/Mpp.txt | 48 ++ Documentation/Marvell/PortingGuide/Spi.txt | 15 + Documentation/Marvell/PortingGuide/SpiFlash.txt | 23 + Drivers/I2c/Devices/MvEeprom/MvEeprom.c | 292 ++++++++ Drivers/I2c/Devices/MvEeprom/MvEeprom.h | 103 +++ Drivers/I2c/Devices/MvEeprom/MvEeprom.inf | 70 ++ Drivers/I2c/MvI2cDxe/MvI2cDxe.c | 739 +++++++++++++++++++++ Drivers/I2c/MvI2cDxe/MvI2cDxe.h | 269 ++++++++ Drivers/I2c/MvI2cDxe/MvI2cDxe.inf | 75 +++ Drivers/Spi/Devices/MvSpiFlash.c | 531 +++++++++++++++ Drivers/Spi/Devices/MvSpiFlash.h | 132 ++++ Drivers/Spi/Devices/MvSpiFlash.inf | 67 ++ Drivers/Spi/MvSpiDxe.c | 379 +++++++++++ Drivers/Spi/MvSpiDxe.h | 145 ++++ Drivers/Spi/MvSpiDxe.inf | 66 ++ Platforms/Marvell/Armada/Armada.dsc.inc | 453 +++++++++++++ Platforms/Marvell/Armada/Armada70x0.dsc | 97 +++ Platforms/Marvell/Armada/Armada70x0.fdf | 270 ++++++++ .../Armada70x0Lib/AArch64/ArmPlatformHelper.S | 66 ++ .../Armada/Library/Armada70x0Lib/Armada70x0Lib.c | 155 +++++ .../Armada/Library/Armada70x0Lib/Armada70x0Lib.inf | 69 ++ .../Library/Armada70x0Lib/Armada70x0LibMem.c | 93 +++ Platforms/Marvell/Include/Library/MppLib.h | 42 ++ Platforms/Marvell/Include/Library/ParsePcdLib.h | 46 ++ Platforms/Marvell/Include/Protocol/Eeprom.h | 60 ++ Platforms/Marvell/Include/Protocol/Spi.h | 105 +++ Platforms/Marvell/Include/Protocol/SpiFlash.h | 113 ++++ Platforms/Marvell/Library/MppLib/MppLib.c | 163 +++++ Platforms/Marvell/Library/MppLib/MppLib.inf | 107 +++ .../Marvell/Library/ParsePcdLib/ParsePcdLib.c | 228 +++++++ .../Marvell/Library/ParsePcdLib/ParsePcdLib.inf | 50 ++ Platforms/Marvell/Marvell.dec | 136 ++++ 45 files changed, 7088 insertions(+) create mode 100644 Applications/EepromCmd/EepromCmd.c create mode 100644 Applications/EepromCmd/EepromCmd.inf create mode 100644 Applications/EepromCmd/EepromCmd.uni create mode 100644 Applications/FirmwareUpdate/FUpdate.c create mode 100644 Applications/FirmwareUpdate/FUpdate.inf create mode 100644 Applications/FirmwareUpdate/FUpdate.uni create mode 100644 Applications/SpiTool/SpiFlashCmd.c create mode 100644 Applications/SpiTool/SpiFlashCmd.inf create mode 100644 Applications/SpiTool/SpiFlashCmd.uni create mode 100644 Documentation/Marvell/Drivers/EepromDriver.txt create mode 100644 Documentation/Marvell/Drivers/I2cDriver.txt create mode 100644 Documentation/Marvell/Drivers/SpiDriver.txt create mode 100644 Documentation/Marvell/PortingGuide/I2c.txt create mode 100644 Documentation/Marvell/PortingGuide/Mpp.txt create mode 100644 Documentation/Marvell/PortingGuide/Spi.txt create mode 100644 Documentation/Marvell/PortingGuide/SpiFlash.txt create mode 100644 Drivers/I2c/Devices/MvEeprom/MvEeprom.c create mode 100644 Drivers/I2c/Devices/MvEeprom/MvEeprom.h create mode 100644 Drivers/I2c/Devices/MvEeprom/MvEeprom.inf create mode 100755 Drivers/I2c/MvI2cDxe/MvI2cDxe.c create mode 100644 Drivers/I2c/MvI2cDxe/MvI2cDxe.h create mode 100755 Drivers/I2c/MvI2cDxe/MvI2cDxe.inf create mode 100755 Drivers/Spi/Devices/MvSpiFlash.c create mode 100755 Drivers/Spi/Devices/MvSpiFlash.h create mode 100644 Drivers/Spi/Devices/MvSpiFlash.inf create mode 100755 Drivers/Spi/MvSpiDxe.c create mode 100644 Drivers/Spi/MvSpiDxe.h create mode 100644 Drivers/Spi/MvSpiDxe.inf create mode 100644 Platforms/Marvell/Armada/Armada.dsc.inc create mode 100644 Platforms/Marvell/Armada/Armada70x0.dsc create mode 100644 Platforms/Marvell/Armada/Armada70x0.fdf create mode 100644 Platforms/Marvell/Armada/Library/Armada70x0Lib/AArch64/ArmPlatformHelper.S create mode 100644 Platforms/Marvell/Armada/Library/Armada70x0Lib/Armada70x0Lib.c create mode 100644 Platforms/Marvell/Armada/Library/Armada70x0Lib/Armada70x0Lib.inf create mode 100644 Platforms/Marvell/Armada/Library/Armada70x0Lib/Armada70x0LibMem.c create mode 100644 Platforms/Marvell/Include/Library/MppLib.h create mode 100644 Platforms/Marvell/Include/Library/ParsePcdLib.h create mode 100644 Platforms/Marvell/Include/Protocol/Eeprom.h create mode 100644 Platforms/Marvell/Include/Protocol/Spi.h create mode 100644 Platforms/Marvell/Include/Protocol/SpiFlash.h create mode 100644 Platforms/Marvell/Library/MppLib/MppLib.c create mode 100644 Platforms/Marvell/Library/MppLib/MppLib.inf create mode 100644 Platforms/Marvell/Library/ParsePcdLib/ParsePcdLib.c create mode 100644 Platforms/Marvell/Library/ParsePcdLib/ParsePcdLib.inf create mode 100644 Platforms/Marvell/Marvell.dec
-- 1.8.3.1
Thanks a lot Leif! We can discuss 21-22 later and now we can proceed with submitting remaining interfaces.
Best regards, Marcin
2016-07-11 19:33 GMT+02:00 Leif Lindholm leif.lindholm@linaro.org:
On Sun, Jul 10, 2016 at 02:21:24AM +0200, Marcin Wojtas wrote:
Hello,
Here's 6th version of the support. It's rebased on top of newest master branch and comprise fixes from the latest review.
Patches are also available in the github: https://github.com/MarvellEmbeddedProcessors/edk2-open-platform/commits/opp-...
Any comments or remarks would be welcome.
Hi Marcin. I have now pushed 1-20/23 to OpenPlatformPkg master. 21-22, I still want to give some more thought, and 23 we've agreed to drop.
Many thanks for your contribution.
Regards,
Leif
Best regards, Marcin
Changelog: v5 -> v6
- Initial support
- Enable compilation after ArmMmuLib was added to edk2
- Remove commented-out line
- Enable up to 64MB RamDisk space for all Armada platforms
- Move adding "-fno-unwind-tables" build flag to a separate patch and add explanation for this change
- I2C
- Change MvI2cDevicePathProtocol to STATIC in MvI2cDxe.c
- Generate new I2C_GUID
- Move I2C_GUID to header files and extend existing FIXME comment
- Fupdate
- Add FIXME note over including relative path from edk2. It was needed after fixing regression by replacing ShellExecute with RunShellCommand
v4 -> v5
- Add ParsePcdLib
- Library created in order to parse PCD strings - it makes support for multi-controller easier to implement
- I2c
- Introduce multi-bus support
- Remove comments regarding GUID-slave address dependency
- Add FIXME comment about no-restart dual definition
- eeprom command
- Enable selecting I2C bus
- Add FIXME comment about no-restart dual definition
- Spi
- Fix writing procedure
- Rename protocol to MARVELL_SPI_MASTER_PROTOCOL
- General
- Remove commented-out, unused lines
v3 -> v4
- Update license messages
- Unify
- Add "Based on" statement were needed
- Wrap every message at 80 characters
- Add Marvell copyrights
- Fix namings
- All protocol/file names updated as suggested in review
- Clean-up
- Remove unneded blank lines and spaces
- Fix typos
- Add "Reviewed by" for currently accepted patches
- Add support for new platform - Armada70x0
- Remove support for old platforms Apn806 and Armada7040_rz
- Armada70x0 is based on Armada7040_rz with silicone fixes and improvements
- No changes on drivers/libraries caused by this change
- Update commit logs in whole tree
- MppLib
- Fix issue with writing to uninitialized memory
- I2c and eeprom command
- Remove dependency on BdsLibConnectAll call
- I2c stack is connected only if eeprom command is executed and only in case it wasn't done before
- gBS->ConnectController() used
- BdsLib
- Remove import of BdsLib
- After rebase on top of new edk2, extra BdsLibConnectAll call isn't necessary (actually for now no BdsLibConnectAll is needed at all for our platform support)
- sf command
- Remove inclusion of relative path
- Necessary macro now defined in globally exported file
- RamDisk driver
- Drop patch with this feature
- As long as there is no possibility to format RamDisk with FAT, driver is not useful on Armada70x0
- fupdate command
- Fix issue with "bad checksum"
v2 -> v3
- Decrease binary size
- Fupdate command
- Remove regression - replace ShellExecute with RunShellCommand
- Improve error paths
- Add proper DEBUG library and change error print levels
v1 -> v2
- Fix "may be used uninitialized" variables issue, branch compiles both with DEBUG and RELEASE flags
- Remove I2C_FLAG_NORESTART dependency - replace it with local definition
- Remove Marvell UART Library:
Since in edk2 there is support for 16550, internal library is unnecessary.
- DW8250 IP has programming interface compatible with NS-16550.
- /Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf is used instead
- RamDisk driver:
- Remove old driver imported from EFI TOOLKIT 2.0
- Replace it with new MdeModulePkg/Universal/Disk/RamDiskDxe from edk2
- Lack of FAT formatting issue emerged
- Add explicit dependency on IoLib in Drivers/Spi/SpiDxe.inf
- Add poster's "Signed-off-by" registry to every commit message
- Move to 05.04.2016 HEAD of edk2/master
- Update CpuExceptionHandlerLib within OPP.
Bartosz Szczepanek (3): Drivers/I2c: Create MvI2cDxe driver Drivers/I2c: Add MvEeprom driver Aplications/Eeprom: Add 'eeprom' command to shell
Haim Boot (1): Platforms/Marvell: Enable compilation with aarch64-linux-gnueabi toolchain
Jan Dąbroś (17): Platforms/Marvell: Create MppLib Platforms/Marvell: Armada: Enable MppLib on Armada70x0 platform Platforms/Marvell: Create ParsePcdLib Platforms/Marvell: Enable ParsePcdLib for Armada70x0 platform Platforms/Marvell: Enable I2C driver on Armada70x0 platform Plaforms/Marvell: Enable EEPROM driver on Armada70x0 platform Platforms/Marvell: Enable 'eeprom' command on Armada70x0 platform Platforms/Marvell: Add MARVELL_SPI_MASTER_PROTOCOL Drivers/Spi: Add Spi master driver Platforms/Marvell: Enable Spi master driver for Armada70x0 platform Platforms/Marvell: Add MARVELL_SPI_FLASH_PROTOCOL Drivers/Spi: Implement Spi flash driver Platforms/Marvell: Enable Spi flash driver for Armada70x0 platform Applications/SpiTool: Add 'sf' command utility Platforms/Marvell: Enable 'sf' command on Armada70x0 platform Applications/FirmwareUpdate: Add 'fupdate' comand to shell Platforms/Marvell: Enable 'fupdate' command on Armada70x0 platform
Yehuda Yitschak (2): Platforms/Marvell: Add initial support for Armada70x0 SOC lib Platforms/Marvell: Add support for Armada70x0 platform
Applications/EepromCmd/EepromCmd.c | 397 +++++++++++ Applications/EepromCmd/EepromCmd.inf | 71 ++ Applications/EepromCmd/EepromCmd.uni | Bin 0 -> 6816 bytes Applications/FirmwareUpdate/FUpdate.c | 448 +++++++++++++ Applications/FirmwareUpdate/FUpdate.inf | 68 ++ Applications/FirmwareUpdate/FUpdate.uni | Bin 0 -> 5838 bytes Applications/SpiTool/SpiFlashCmd.c | 526 +++++++++++++++ Applications/SpiTool/SpiFlashCmd.inf | 75 +++ Applications/SpiTool/SpiFlashCmd.uni | Bin 0 -> 7216 bytes Documentation/Marvell/Drivers/EepromDriver.txt | 96 +++ Documentation/Marvell/Drivers/I2cDriver.txt | 64 ++ Documentation/Marvell/Drivers/SpiDriver.txt | 116 ++++ Documentation/Marvell/PortingGuide/I2c.txt | 20 + Documentation/Marvell/PortingGuide/Mpp.txt | 48 ++ Documentation/Marvell/PortingGuide/Spi.txt | 15 + Documentation/Marvell/PortingGuide/SpiFlash.txt | 23 + Drivers/I2c/Devices/MvEeprom/MvEeprom.c | 292 ++++++++ Drivers/I2c/Devices/MvEeprom/MvEeprom.h | 103 +++ Drivers/I2c/Devices/MvEeprom/MvEeprom.inf | 70 ++ Drivers/I2c/MvI2cDxe/MvI2cDxe.c | 739 +++++++++++++++++++++ Drivers/I2c/MvI2cDxe/MvI2cDxe.h | 269 ++++++++ Drivers/I2c/MvI2cDxe/MvI2cDxe.inf | 75 +++ Drivers/Spi/Devices/MvSpiFlash.c | 531 +++++++++++++++ Drivers/Spi/Devices/MvSpiFlash.h | 132 ++++ Drivers/Spi/Devices/MvSpiFlash.inf | 67 ++ Drivers/Spi/MvSpiDxe.c | 379 +++++++++++ Drivers/Spi/MvSpiDxe.h | 145 ++++ Drivers/Spi/MvSpiDxe.inf | 66 ++ Platforms/Marvell/Armada/Armada.dsc.inc | 453 +++++++++++++ Platforms/Marvell/Armada/Armada70x0.dsc | 97 +++ Platforms/Marvell/Armada/Armada70x0.fdf | 270 ++++++++ .../Armada70x0Lib/AArch64/ArmPlatformHelper.S | 66 ++ .../Armada/Library/Armada70x0Lib/Armada70x0Lib.c | 155 +++++ .../Armada/Library/Armada70x0Lib/Armada70x0Lib.inf | 69 ++ .../Library/Armada70x0Lib/Armada70x0LibMem.c | 93 +++ Platforms/Marvell/Include/Library/MppLib.h | 42 ++ Platforms/Marvell/Include/Library/ParsePcdLib.h | 46 ++ Platforms/Marvell/Include/Protocol/Eeprom.h | 60 ++ Platforms/Marvell/Include/Protocol/Spi.h | 105 +++ Platforms/Marvell/Include/Protocol/SpiFlash.h | 113 ++++ Platforms/Marvell/Library/MppLib/MppLib.c | 163 +++++ Platforms/Marvell/Library/MppLib/MppLib.inf | 107 +++ .../Marvell/Library/ParsePcdLib/ParsePcdLib.c | 228 +++++++ .../Marvell/Library/ParsePcdLib/ParsePcdLib.inf | 50 ++ Platforms/Marvell/Marvell.dec | 136 ++++ 45 files changed, 7088 insertions(+) create mode 100644 Applications/EepromCmd/EepromCmd.c create mode 100644 Applications/EepromCmd/EepromCmd.inf create mode 100644 Applications/EepromCmd/EepromCmd.uni create mode 100644 Applications/FirmwareUpdate/FUpdate.c create mode 100644 Applications/FirmwareUpdate/FUpdate.inf create mode 100644 Applications/FirmwareUpdate/FUpdate.uni create mode 100644 Applications/SpiTool/SpiFlashCmd.c create mode 100644 Applications/SpiTool/SpiFlashCmd.inf create mode 100644 Applications/SpiTool/SpiFlashCmd.uni create mode 100644 Documentation/Marvell/Drivers/EepromDriver.txt create mode 100644 Documentation/Marvell/Drivers/I2cDriver.txt create mode 100644 Documentation/Marvell/Drivers/SpiDriver.txt create mode 100644 Documentation/Marvell/PortingGuide/I2c.txt create mode 100644 Documentation/Marvell/PortingGuide/Mpp.txt create mode 100644 Documentation/Marvell/PortingGuide/Spi.txt create mode 100644 Documentation/Marvell/PortingGuide/SpiFlash.txt create mode 100644 Drivers/I2c/Devices/MvEeprom/MvEeprom.c create mode 100644 Drivers/I2c/Devices/MvEeprom/MvEeprom.h create mode 100644 Drivers/I2c/Devices/MvEeprom/MvEeprom.inf create mode 100755 Drivers/I2c/MvI2cDxe/MvI2cDxe.c create mode 100644 Drivers/I2c/MvI2cDxe/MvI2cDxe.h create mode 100755 Drivers/I2c/MvI2cDxe/MvI2cDxe.inf create mode 100755 Drivers/Spi/Devices/MvSpiFlash.c create mode 100755 Drivers/Spi/Devices/MvSpiFlash.h create mode 100644 Drivers/Spi/Devices/MvSpiFlash.inf create mode 100755 Drivers/Spi/MvSpiDxe.c create mode 100644 Drivers/Spi/MvSpiDxe.h create mode 100644 Drivers/Spi/MvSpiDxe.inf create mode 100644 Platforms/Marvell/Armada/Armada.dsc.inc create mode 100644 Platforms/Marvell/Armada/Armada70x0.dsc create mode 100644 Platforms/Marvell/Armada/Armada70x0.fdf create mode 100644 Platforms/Marvell/Armada/Library/Armada70x0Lib/AArch64/ArmPlatformHelper.S create mode 100644 Platforms/Marvell/Armada/Library/Armada70x0Lib/Armada70x0Lib.c create mode 100644 Platforms/Marvell/Armada/Library/Armada70x0Lib/Armada70x0Lib.inf create mode 100644 Platforms/Marvell/Armada/Library/Armada70x0Lib/Armada70x0LibMem.c create mode 100644 Platforms/Marvell/Include/Library/MppLib.h create mode 100644 Platforms/Marvell/Include/Library/ParsePcdLib.h create mode 100644 Platforms/Marvell/Include/Protocol/Eeprom.h create mode 100644 Platforms/Marvell/Include/Protocol/Spi.h create mode 100644 Platforms/Marvell/Include/Protocol/SpiFlash.h create mode 100644 Platforms/Marvell/Library/MppLib/MppLib.c create mode 100644 Platforms/Marvell/Library/MppLib/MppLib.inf create mode 100644 Platforms/Marvell/Library/ParsePcdLib/ParsePcdLib.c create mode 100644 Platforms/Marvell/Library/ParsePcdLib/ParsePcdLib.inf create mode 100644 Platforms/Marvell/Marvell.dec
-- 1.8.3.1