/** @file Copyright (c) 2017, Linaro 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 #include #include #include #include #include #define UEFI_IMAGE_OFFSET FixedPcdGet64 (PcdFvBaseAddress) - FixedPcdGet64 (PcdFdBaseAddress) #define BLOCK_SIZE SIZE_64KB STATIC AMD_ISCP_DXE_PROTOCOL *mIscpDxeProtocol; STATIC UINT8 Buffer[BLOCK_SIZE]; extern CONST UINT8 StyxFlashImageStart[]; extern CONST UINT32 StyxFlashImageSize; /*** Main entrypoint Establishes the main structure of the application. @retval 0 The application exited normally. @retval Other An error occurred. ***/ INTN EFIAPI ShellAppMain ( IN UINTN Argc, IN CHAR16 **Argv ) { EFI_STATUS Status; UINTN Index; INTN Remaining; Print (L"StyxFlashUefi: firmware updater for AMD Seattle based boards.\n"); Status = gBS->LocateProtocol (&gAmdIscpDxeProtocolGuid, NULL, (VOID **)&mIscpDxeProtocol); if (EFI_ERROR (Status)) { Print (L"Failed to locate ISCP communication protocol, terminating...\n"); return (INTN)Status; } Index = 0; Remaining = StyxFlashImageSize; do { Status = mIscpDxeProtocol->AmdExecuteEraseFvBlockDxe ( mIscpDxeProtocol, UEFI_IMAGE_OFFSET + Index * BLOCK_SIZE, BLOCK_SIZE); if (EFI_ERROR (Status)) { Print (L"Erase failed!\n"); return (INTN)Status; } CopyMem (Buffer, StyxFlashImageStart + Index * BLOCK_SIZE, MIN (Remaining, BLOCK_SIZE)); Status = mIscpDxeProtocol->AmdExecuteUpdateFvBlockDxe ( mIscpDxeProtocol, UEFI_IMAGE_OFFSET + Index * BLOCK_SIZE, Buffer, MIN (Remaining, BLOCK_SIZE)); if (EFI_ERROR (Status)) { Print (L"Update failed!\n"); return (INTN)Status; } Remaining -= BLOCK_SIZE; Index++; Print (L"Block %d of %d updated\n", Index, StyxFlashImageSize / BLOCK_SIZE); } while (Remaining > 0); Print (L"\nDone!\n"); return 0; }