From: Duke Zhai <Duke.Zhai@amd.com>
BZ #:4640
In V2: Improve coding style.
1.Remove the leading underscore and use double underscore at trailing in C header files.
2.Remove old tianocore licenses and redundant license description.
3.Improve coding style. For example: remove space between @param.
In V1:
UDKFlashUpdate is a uefi tool for BIOS binary updating. It depends on EDK2's flash access protocol.
UDKFlashUpdate needs to run under EDK2 BIOS.
Signed-off-by: Duke Zhai <duke.zhai@amd.com>
Cc: Eric Xing <eric.xing@amd.com>
Cc: Ken Yao <ken.yao@amd.com>
Cc: Igniculus Fu <igniculus.fu@amd.com>
Cc: Abner Chang <abner.chang@amd.com>
---
.../UDKFlashUpdate/SpiFlashDevice.c | 37 +
.../UDKFlashUpdate/SpiFlashDevice.h | 62 ++
.../UDKFlashUpdate/UDKFlashUpdate.c | 671 ++++++++++++++++++
.../UDKFlashUpdate/UDKFlashUpdate.h | 48 ++
.../UDKFlashUpdate/UDKFlashUpdate.inf | 51 ++
5 files changed, 869 insertions(+)
create mode 100644 Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Application/UDKFlashUpdate/SpiFlashDevice.c
create mode 100644 Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Application/UDKFlashUpdate/SpiFlashDevice.h
create mode 100644 Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Application/UDKFlashUpdate/UDKFlashUpdate.c
create mode 100644 Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Application/UDKFlashUpdate/UDKFlashUpdate.h
create mode 100644 Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Application/UDKFlashUpdate/UDKFlashUpdate.inf
diff --git a/Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Application/UDKFlashUpdate/SpiFlashDevice.c b/Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Application/UDKFlashUpdate/SpiFlashDevice.c
new file mode 100644
index 0000000000..d4f5b12f41
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Application/UDKFlashUpdate/SpiFlashDevice.c
@@ -0,0 +1,37 @@
+/** @file
+ Implements SpiFlashDevice.c
+
+ Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "SpiFlashDevice.h"
+
+SPI_INIT_TABLE mSpiInitTable[] = {
+ { // W25Q256JW/W74M25JW
+ SF_VENDOR_ID_WINBOND,
+ SF_DEVICE_ID0_W25Q256JW,
+ SF_DEVICE_ID1_W25Q256JW,
+ {
+ SPI_COMMAND_WRITE_ENABLE,
+ SPI_COMMAND_WRITE_S_EN
+ },
+ {
+ { EnumSpiOpcodeReadNoAddr,SPI_COMMAND_JEDEC_ID, EnumSpiOperationJedecId },
+ { EnumSpiOpcodeWriteNoAddr,SPI_COMMAND_WRITE_S, EnumSpiOperationWriteStatus },
+ { EnumSpiOpcodeWrite, SPI_COMMAND_WRITE, EnumSpiOperationProgramData_1_Byte },
+ { EnumSpiOpcodeRead, SPI_COMMAND_READ, EnumSpiOperationReadData },
+ { EnumSpiOpcodeWrite, SPI_COMMAND_ERASE, EnumSpiOperationErase_4K_Byte },
+ { EnumSpiOpcodeReadNoAddr,SPI_COMMAND_READ_S, EnumSpiOperationReadStatus },
+ { EnumSpiOpcodeWriteNoAddr,SPI_COMMAND_CHIP_ERASE, EnumSpiOperationFullChipErase },
+ { EnumSpiOpcodeRead, SPI_COMMAND_READ_SFDP, EnumSpiOperationReadData },
+ { EnumSpiOpcodeWriteNoAddr,SPI_COMMAND_RPMC_OP1, EnumSpiOperationOther },
+ { EnumSpiOpcodeReadNoAddr,SPI_COMMAND_RPMC_OP2, EnumSpiOperationReadData },
+ { EnumSpiOpcodeReadNoAddr,SPI_COMMAND_Enter_4Byte_Addr, EnumSpiOperationOther },
+ { EnumSpiOpcodeReadNoAddr,SPI_COMMAND_Exit_4Byte_Addr, EnumSpiOperationOther }
+ },
+ 0,
+ 0x2000000 // BIOS image size in flash
+ }
+};
diff --git a/Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Application/UDKFlashUpdate/SpiFlashDevice.h b/Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Application/UDKFlashUpdate/SpiFlashDevice.h
new file mode 100644
index 0000000000..fe4d99e82c
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Application/UDKFlashUpdate/SpiFlashDevice.h
@@ -0,0 +1,62 @@
+/** @file
+ Implements SpiFlashDevice.h
+
+ Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef SPI_FLASH_DEVICE_H__
+#define SPI_FLASH_DEVICE_H__
+
+#include <PiDxe.h>
+#include <Protocol/Spi.h>
+#include <Protocol/SpiCommon.h>
+
+//
+// Supported SPI Flash Devices
+//
+typedef enum {
+ EnumSpiFlashW25Q256JW,
+ EnumSpiFlashMax
+} SPI_FLASH_TYPES_SUPPORTED;
+
+// Flash Device commands
+//
+// If a supported device uses a command different from the list below, a device specific command
+// will be defined just below it's JEDEC id section.
+//
+#define SPI_COMMAND_WRITE 0x02
+#define SPI_COMMAND_WRITE_AAI 0xAD
+#define SPI_COMMAND_READ 0x03
+#define SPI_COMMAND_ERASE 0x20
+#define SPI_COMMAND_WRITE_DISABLE 0x04
+#define SPI_COMMAND_READ_S 0x05
+#define SPI_COMMAND_WRITE_ENABLE 0x06
+#define SPI_COMMAND_READ_ID 0xAB
+#define SPI_COMMAND_JEDEC_ID 0x9F
+#define SPI_COMMAND_WRITE_S_EN 0x50
+#define SPI_COMMAND_WRITE_S 0x01
+#define SPI_COMMAND_CHIP_ERASE 0xC7
+#define SPI_COMMAND_BLOCK_ERASE 0xD8
+#define SPI_COMMAND_READ_SFDP 0x5A
+#define SPI_COMMAND_RPMC_OP1 0x9B
+#define SPI_COMMAND_RPMC_OP2 0x96
+#define SPI_COMMAND_Enter_4Byte_Addr 0xB7
+#define SPI_COMMAND_Exit_4Byte_Addr 0xE9
+
+//
+// Winbond 256Mbit parts
+//
+#define SF_VENDOR_ID_WINBOND 0xEF
+#define SF_DEVICE_ID1_W25Q256JW 0x19 // Capacity 256Mbit
+#define SF_DEVICE_ID0_W25Q256JW 0x60
+
+//
+// index for prefix opcodes
+//
+#define SPI_WREN_INDEX 0 // Prefix Opcode 0: SPI_COMMAND_WRITE_ENABLE
+#define SPI_EWSR_INDEX 1 // Prefix Opcode 1: SPI_COMMAND_WRITE_S_EN
+#define BIOS_CTRL 0xDC
+
+#endif
diff --git a/Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Application/UDKFlashUpdate/UDKFlashUpdate.c b/Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Application/UDKFlashUpdate/UDKFlashUpdate.c
new file mode 100644
index 0000000000..0497509d03
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Application/UDKFlashUpdate/UDKFlashUpdate.c
@@ -0,0 +1,671 @@
+/** @file
+ Platform Flash Access library.
+
+ Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+ Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "UDKFlashUpdate.h"
+
+EFI_SPI_PROTOCOL *mSpiProtocol = NULL;
+UINT32 mFlashAreaBaseAddress;
+UINTN mBiosSize;
+UINTN mBlockSize;
+
+/**
+ Input the BeginTimeValue and EndTimeValue, return the spent time(seconds).
+
+ @param[in] BeginTimeValue The begin time value read by AsmReadTsc().
+ @param[in] EndTimeValue The end time value read by AsmReadTsc().
+
+ @retval -1 An error occurred.
+ @retval other The seconds value.
+
+**/
+STATIC
+INT64
+EFIAPI
+GetSpentTime (
+ IN UINT64 EndTimeValue,
+ IN UINT64 BeginTimeValue
+ )
+{
+ if (EndTimeValue >= BeginTimeValue) {
+ return (DivU64x32 (GetTimeInNanoSecond (EndTimeValue - BeginTimeValue), 1000000000));
+ } else {
+ Print (L"!!!ERROR: Wrong time\n");
+ return (-1);
+ }
+}
+
+/**
+ Read 'ReadAddress|NumBytes' of the flash chip, and saved into 'ReadFlash.bin'
+
+ @param[in] ReadAddress Read address base in flash chip.
+ @param[in] NumBytes Read number of bytes.
+
+ @retval 0 Flash read exited normally.
+ @retval Other An error occurred.
+
+**/
+UINTN
+EFIAPI
+FlashFdRead (
+ IN UINTN ReadAddress,
+ IN UINTN NumBytes,
+ IN CHAR16 *FileName
+ )
+{
+ EFI_STATUS Status;
+ VOID *Buffer;
+ SHELL_FILE_HANDLE FileHandle;
+
+ Print (L"\nRead flash chip and saved into %s ...\n", FileName);
+
+ Buffer = AllocateZeroPool (NumBytes);
+ if (NULL == Buffer) {
+ Print (L"!!!ERROR: Allocate pool fail ...\n");
+ return (1);
+ }
+
+ Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, 0);
+ if (EFI_ERROR (Status)) {
+ Print (L"!!!ERROR: Open file %s %r\n", FileName, Status);
+ FreePool (Buffer);
+ return (1);
+ }
+
+ CopyMem ((UINT8 *)Buffer, (UINT8 *)(ReadAddress + mFlashAreaBaseAddress), NumBytes);
+ Status = ShellWriteFile (FileHandle, &NumBytes, Buffer);
+ if (EFI_ERROR (Status)) {
+ Print (L"!!!ERROR: Write file %s %r\n", FileName, Status);
+ FreePool (Buffer);
+ ShellCloseFile (&FileHandle);
+ return (1);
+ }
+
+ FreePool (Buffer);
+ ShellCloseFile (&FileHandle);
+
+ return (0);
+}
+
+/**
+ Erase 'EraseAddress|NumBytes' in flash chip, and skip the block all '0xFF'.
+
+ @param[in] EraseAddress Erase address base.
+ @param[in] NumBytes Erase number of bytes.
+
+ @retval 0 Flash erase exited normally.
+ @retval Other An error occurred.
+
+**/
+UINTN
+EFIAPI
+FlashFd64KErase (
+ IN UINTN EraseAddress,
+ IN UINTN NumBytes
+ )
+{
+ EFI_STATUS Status;
+ // UINTN Index;
+ UINT8 *Buffer;
+
+ Print (L"\nErase flash chip ");
+
+ Buffer = AllocateZeroPool (NumBytes);
+ if (NULL == Buffer) {
+ Print (L"!!!ERROR: Allocate fail ...\n");
+ return (1);
+ }
+
+ CopyMem (Buffer, (UINT8 *)(EraseAddress + mFlashAreaBaseAddress), NumBytes);
+
+ for ( ; EraseAddress < NumBytes; EraseAddress += mBlockSize) {
+ Status = mSpiProtocol->Execute (
+ mSpiProtocol,
+ SPI_OPCODE_ERASE_INDEX, // OpcodeIndex
+ 0, // PrefixOpcodeIndex
+ FALSE, // DataCycle
+ TRUE, // Atomic
+ TRUE, // ShiftOut
+ EraseAddress, // Address
+ 0, // Data Number
+ NULL,
+ EnumSpiRegionBios // SPI_REGION_TYPE
+ );
+ Print (L"Erase address = 0x%x, Erase %r\n", EraseAddress, Status);
+ if (EFI_ERROR (Status)) {
+ FreePool (Buffer);
+ Print (L"!!!ERROR: Erase flash %r\n", Status);
+ return (1);
+ }
+ }
+
+ FreePool (Buffer);
+ AsmWbinvd ();
+
+ return (0);
+}
+
+/**
+ Write 'WriteAddress|NumBytes' in flash chip and skip the block all '0xFF'.
+
+ @param[in] WriteAddress Write address base in flash chip.
+ @param[in] NumBytes Write number of bytes.
+ @param[in] Buffer Point to contents going to write into flash chip.
+
+ @retval 0 Flash write exited normally.
+ @retval Other An error occurred.
+
+**/
+UINTN
+EFIAPI
+FlashFdWrite (
+ IN UINTN WriteAddress,
+ IN UINTN NumBytes,
+ IN UINT8 *Buffer
+ )
+{
+ EFI_STATUS Status;
+ UINTN Index;
+
+ Print (L"\nWrite flash chip ");
+
+ for ( ; WriteAddress < NumBytes; WriteAddress += mBlockSize) {
+ for (Index = 0; Index < mBlockSize; Index++) {
+ if (0xFF != *(Buffer + Index)) {
+ Print (L"FlashFdWrite WriteAddress= 0x%x\n", WriteAddress);
+ Status = mSpiProtocol->Execute (
+ mSpiProtocol,
+ SPI_OPCODE_WRITE_INDEX, // OpcodeIndex
+ 0, // PrefixOpcodeIndex
+ TRUE, // DataCycle
+ TRUE, // Atomic
+ TRUE, // ShiftOut
+ WriteAddress, // Address
+ (UINT32)mBlockSize, // Data Number
+ Buffer,
+ EnumSpiRegionBios
+ );
+ if (EFI_ERROR (Status)) {
+ Print (L"!!!ERROR: Write flash %r\n", Status);
+ return (1);
+ } else {
+ Print (L".");
+ }
+
+ break;
+ }
+ }
+
+ Buffer += mBlockSize;
+ }
+
+ Print (L"\nWrite flash chip success\n");
+ AsmWbinvd ();
+
+ return (0);
+}
+
+/**
+ Verify the binary in flash chip and the source binary use checksum.
+
+ @param[in] BaseAddress Write address base in memory.
+ @param[in] NumBytes Write total number of bytes.
+ @param[in] Sourcefile Point to contents writed into flash chip.
+
+ @retval 0 Flash verify exited normally.
+ @retval Other An error occurred.
+
+**/
+UINTN
+EFIAPI
+FlashFdVerify (
+ IN UINTN BaseAddress,
+ IN UINTN NumBytes,
+ IN VOID *Sourcefile
+ )
+{
+ UINT8 *Buffer;
+ UINT32 Index;
+ UINT32 ChecksumSourceFile;
+ UINT32 ChecksumFlash;
+
+ Print (L"\n");
+
+ ChecksumSourceFile = 0;
+ ChecksumFlash = 0;
+
+ Buffer = AllocateZeroPool (NumBytes);
+ if (NULL == Buffer) {
+ Print (L"!!!ERROR: Allocate fail ...\n");
+ return (1);
+ }
+
+ CopyMem (Buffer, (UINT8 *)(BaseAddress + mFlashAreaBaseAddress), NumBytes);
+ for (Index = 0; Index < NumBytes; Index++) {
+ ChecksumFlash += *(UINT8 *)(Buffer + Index);
+ ChecksumSourceFile += *((UINT8 *)Sourcefile + Index);
+ }
+
+ Print (L"Flash checksum: 0x%x, Source File checksum: 0x%x\n", ChecksumFlash, ChecksumSourceFile);
+
+ if (ChecksumSourceFile == ChecksumFlash) {
+ Print (L"Verify success\n");
+ } else {
+ Print (L"!!!ERROR: Verify fail\n");
+ FreePool (Buffer);
+ return (1);
+ }
+
+ FreePool (Buffer);
+
+ return (0);
+}
+
+/**
+ Initialize.
+
+ @retval 0 Flash erase exited normally.
+ @retval Other An error occurred.
+
+**/
+UINTN
+EFIAPI
+Initialize (
+ IN UINT8 *Index
+ )
+{
+ EFI_STATUS Status;
+ UINT8 FlashIndex;
+ UINT8 FlashID[3];
+ SPI_INSTANCE *SpiInstance;
+
+ mSpiProtocol = NULL;
+
+ Status = gBS->LocateProtocol (&gEfiSpiProtocolGuid, NULL, (VOID **)&mSpiProtocol);
+ if (EFI_ERROR (Status)) {
+ Print (L"!!!ERROR: Locate SpiProtocol %r\n", Status);
+ FreePool (mSpiProtocol);
+ return (1);
+ }
+
+ //
+ // attempt to identify flash part and initialize spi table
+ //
+ for (FlashIndex = 0; FlashIndex < EnumSpiFlashMax; FlashIndex++) {
+ Status = mSpiProtocol->Init (
+ mSpiProtocol
+ );
+ if (!EFI_ERROR (Status)) {
+ //
+ // read vendor/device IDs to check if flash device is supported
+ //
+ Status = mSpiProtocol->Execute (
+ mSpiProtocol,
+ SPI_OPCODE_JEDEC_ID_INDEX,
+ SPI_WREN_INDEX,
+ TRUE,
+ FALSE,
+ FALSE,
+ 0,
+ 3,
+ FlashID,
+ EnumSpiRegionAll
+ );
+ if (EFI_ERROR (Status)) {
+ return (1);
+ } else {
+ if ((FlashID[0] == mSpiInitTable[FlashIndex].VendorId) &&
+ (FlashID[1] == mSpiInitTable[FlashIndex].DeviceId0) &&
+ (FlashID[2] == mSpiInitTable[FlashIndex].DeviceId1))
+ {
+ Print (
+ L"Supported SPI Flash device found, Vendor Id: 0x%02x, Device ID: 0x%02x%02x\n",
+ FlashID[0],
+ FlashID[1],
+ FlashID[2]
+ );
+ *Index = FlashIndex;
+ break;
+ }
+ }
+ }
+ }
+
+ SpiInstance = SPI_INSTANCE_FROM_SPIPROTOCOL (mSpiProtocol);
+ mBiosSize = SpiInstance->SpiInitTable.BiosSize;
+ mFlashAreaBaseAddress = (UINT32)(0x100000000 - mBiosSize);
+ mBlockSize = SpiInstance->SpiInitTable.OpcodeMenu[SPI_OPCODE_ERASE_INDEX].Operation;
+ Print (L"BiosSize :0x%x, FlashAreaBaseAddress: 0x%x, Blocksize :0x%x\n", mBiosSize, mFlashAreaBaseAddress, mBlockSize);
+
+ return (0);
+}
+
+/**
+ Print out help information.
+
+**/
+STATIC
+VOID
+PrintHelpInfo (
+ VOID
+ )
+{
+ Print (L"Application to update flash chip. Depends on SpiProtocol.\nSupport flash chip: W25Q64FV/JV, W25Q64FW, MX25U6435F, MX25U12835F.\n\n");
+ Print (L"Usage: FLASHUPDATE option [filename]\n\n");
+ Print (L"Option:\n");
+ Print (L" -help -h This help message\n");
+ Print (L" <file> Specifies the name of the file to write into flash chip\n");
+ Print (L" -v Display version information\n");
+ Print (L" -r Read flash chip and saved into file\n\n");
+ Print (L"Filename:\n");
+ Print (L" Specifies the name of the file to save the contents read\n \
+from flash chip, just need when read flash chip.\n\n");
+}
+
+/**
+ Parse command in shell.
+
+ @param[in] Num The number of items in Str.
+ @param[in] Str Array of pointers to strings.
+
+ @retval 0 The application exited normally.
+ @retval 2 Read flash chip and save into file.
+ @retval Other An error occurred.
+
+**/
+STATIC
+UINTN
+EFIAPI
+ShellCommandParse (
+ IN UINTN Num,
+ IN CHAR16 **Str
+ )
+{
+ EFI_STATUS Status;
+
+ if (Num < 2) {
+ Print (L"FlashUpdate: Too few argument\n\n");
+ PrintHelpInfo ();
+ return (1);
+ } else if (2 == Num) {
+ if (StrLen (Str[1]) == 0) {
+ Print (L"FlashUpdate: Too few argument\n\n");
+ PrintHelpInfo ();
+ return (1);
+ }
+
+ if ((Str[1])[0] == L'-') {
+ //
+ // Parse the arguments.
+ //
+ if (StrCmp (Str[1], L"-v") == 0) {
+ Print (L"FlashUpdate: Version 20230527\n\n");
+ return (1);
+ }
+
+ if (StrCmp (Str[1], L"-r") == 0) {
+ Print (L"FlashUpdate: Too few argument\n\n");
+ PrintHelpInfo ();
+ return (1);
+ }
+
+ if ((StrCmp (Str[1], L"-help") == 0) || (StrCmp (Str[1], L"-h") == 0)) {
+ PrintHelpInfo ();
+ return (1);
+ } else {
+ Print (L"FlashUpdate: Illegal option: '%s'\n\n", Str[1]);
+ PrintHelpInfo ();
+ return (1);
+ }
+ }
+
+ Status = ShellIsFile (Str[1]);
+ if (EFI_ERROR (Status)) {
+ Print (L"FlashUpdate: %s is not a file\n\n", Str[1]);
+ PrintHelpInfo ();
+ return (1);
+ }
+ } else if (3 == Num) {
+ if ((Str[1])[0] == L'-') {
+ if (StrCmp (Str[1], L"-r") == 0) {
+ Print (L"Read flash chip\n");
+ return (2);
+ }
+ }
+
+ Print (L"FlashUpdate: Illegal argument: '%s %s'\n\n", Str[1], Str[2]);
+ PrintHelpInfo ();
+ return (1);
+ } else if (Num > 3) {
+ Print (L"FlashUpdate: Too many argument\n\n");
+ PrintHelpInfo ();
+ return (1);
+ }
+
+ return (0);
+}
+
+/**
+ UEFI application entry point which has an interface similar to a
+ standard C main function.
+
+ The ShellCEntryLib library instance wrappers the actual UEFI application
+ entry point and calls this ShellAppMain function.
+
+ @param[in] Argc The number of items in Argv.
+ @param[in] Argv Array of pointers to strings.
+
+ @retval 0 The application exited normally.
+ @retval Other An error occurred.
+
+**/
+INTN
+EFIAPI
+ShellAppMain (
+ IN UINTN Argc,
+ IN CHAR16 **Argv
+ )
+{
+ VOID *Buffer;
+ EFI_STATUS Status;
+ SHELL_FILE_HANDLE SourceHandle;
+ UINTN SourceFileSize;
+ UINTN BeginTimeValue;
+ UINTN InitTimeValue;
+ UINTN EraseTimeValue;
+ UINTN WriteTimeValue;
+ UINTN VerifyTimeValue;
+ UINTN BaseAddress;
+ UINTN NumBytes;
+ UINT32 Index;
+ UINT8 FlashIndex;
+
+ BeginTimeValue = AsmReadTsc ();
+ SourceHandle = NULL;
+ Buffer = NULL;
+
+ Status = Initialize (&FlashIndex);
+ if (0 != Status) {
+ Print (L"!!!ERROR: Initialize fail\n");
+ return (1);
+ }
+
+ BaseAddress = 0;
+ NumBytes = mBiosSize; // Assign after mBiosSize init in Initialize
+
+ //
+ // Parse the command line.
+ //
+ Status = ShellCommandParse (Argc, Argv);
+ if (1 == Status) {
+ return (1);
+ } else if (2 == Status) {
+ Status = FlashFdRead (BaseAddress, NumBytes, Argv[2]);
+ if (0 != Status) {
+ Print (L"!!!ERROR: Read flash chip fail");
+ return (1);
+ }
+
+ Print (L"Read flash chip and saved into %s success\n", Argv[2]);
+ return (0);
+ }
+
+ //
+ // open source file
+ //
+ Status = ShellOpenFileByName (Argv[1], &SourceHandle, EFI_FILE_MODE_READ, 0);
+ if (EFI_ERROR (Status)) {
+ Print (L"!!!ERROR: Open file %s %r\n", Argv[1], Status);
+ return (1);
+ }
+
+ //
+ // get file size of source file
+ //
+ Status = ShellGetFileSize (SourceHandle, &SourceFileSize);
+ if (EFI_ERROR (Status)) {
+ Print (L"!!!ERROR: Read file %s size %r\n", Argv[1], Status);
+ if (NULL != SourceHandle) {
+ ShellCloseFile (&SourceHandle);
+ }
+
+ return (1);
+ }
+
+ Buffer = AllocateZeroPool (SourceFileSize);
+ if (NULL == Buffer) {
+ Print (L"!!!ERROR: Allocate pool fail ...\n");
+ if (NULL != SourceHandle) {
+ ShellCloseFile (&SourceHandle);
+ }
+
+ return (1);
+ }
+
+ Status = ShellReadFile (SourceHandle, &SourceFileSize, Buffer);
+ if (EFI_ERROR (Status)) {
+ Print (L"!!!ERROR: Read file %s %r\n", Argv[1], Status);
+ if (NULL != SourceHandle) {
+ ShellCloseFile (&SourceHandle);
+ }
+
+ if (NULL != Buffer) {
+ FreePool (Buffer);
+ }
+
+ return (1);
+ }
+
+ Print (
+ L"Supported SPI Flash device found, Vendor Id: 0x%02x, Device ID: 0x%02x%02x\n",
+ mSpiInitTable[FlashIndex].VendorId,
+ mSpiInitTable[FlashIndex].DeviceId0,
+ mSpiInitTable[FlashIndex].DeviceId1
+ );
+
+ InitTimeValue = AsmReadTsc ();
+ Print (L"Init spent time: %d seconds\n", GetSpentTime (InitTimeValue, BeginTimeValue));
+
+ Print (L"Size of %s: 0x%x bytes, Flash size: 0x%x bytes\n", Argv[1], SourceFileSize, mBiosSize);
+ if (mBiosSize != SourceFileSize) {
+ Print (L"!!!ERROR: Bios size is not correct\n");
+ if (NULL != SourceHandle) {
+ ShellCloseFile (&SourceHandle);
+ }
+
+ if (NULL != Buffer) {
+ FreePool (Buffer);
+ }
+
+ return (1);
+ }
+
+ Status = FlashFd64KErase (BaseAddress, NumBytes);
+ if (0 != Status) {
+ Print (L"!!!ERROR: Erase falsh chip fail\n");
+ if (NULL != SourceHandle) {
+ ShellCloseFile (&SourceHandle);
+ }
+
+ if (NULL != Buffer) {
+ FreePool (Buffer);
+ }
+
+ return (1);
+ }
+
+ if (0 != Status) {
+ Print (L"!!!ERROR: Erase falsh chip fail\n");
+ if (NULL != SourceHandle) {
+ ShellCloseFile (&SourceHandle);
+ }
+
+ if (NULL != Buffer) {
+ FreePool (Buffer);
+ }
+
+ return (1);
+ }
+
+ EraseTimeValue = AsmReadTsc ();
+ Print (L"Erase spent time: %d seconds\n", GetSpentTime (EraseTimeValue, InitTimeValue));
+
+ Status = FlashFdWrite (BaseAddress, NumBytes, Buffer);
+ if (0 != Status) {
+ Print (L"!!!ERROR: Write falsh chip fail\n");
+ if (NULL != SourceHandle) {
+ ShellCloseFile (&SourceHandle);
+ }
+
+ if (NULL != Buffer) {
+ FreePool (Buffer);
+ }
+
+ return (1);
+ }
+
+ WriteTimeValue = AsmReadTsc ();
+ Print (L"\nWrite spent time: %d seconds\n", GetSpentTime (WriteTimeValue, EraseTimeValue));
+
+ Status = FlashFdVerify (BaseAddress, NumBytes, (UINT8 *)Buffer);
+ if (0 != Status) {
+ Print (L"!!!ERROR: Verify falsh chip fail\n");
+ if (NULL != SourceHandle) {
+ ShellCloseFile (&SourceHandle);
+ }
+
+ if (NULL != Buffer) {
+ FreePool (Buffer);
+ }
+
+ return (1);
+ }
+
+ VerifyTimeValue = AsmReadTsc ();
+ Print (L"\nWrite flash chip success!\n");
+ Print (L"--------------------------------------------------\n");
+ Print (L"Total spent time: %d seconds\n", GetSpentTime (VerifyTimeValue, BeginTimeValue));
+
+ if (NULL != SourceHandle) {
+ ShellCloseFile (&SourceHandle);
+ }
+
+ if (NULL != Buffer) {
+ FreePool (Buffer);
+ }
+
+ Print (L"\nReady to restart ");
+ for (Index = 0; Index < 4; Index++) {
+ MicroSecondDelay (1000000); // delay 1 second
+ Print (L".");
+ }
+
+ gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
+
+ return (0);
+}
diff --git a/Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Application/UDKFlashUpdate/UDKFlashUpdate.h b/Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Application/UDKFlashUpdate/UDKFlashUpdate.h
new file mode 100644
index 0000000000..ed15a4489a
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Application/UDKFlashUpdate/UDKFlashUpdate.h
@@ -0,0 +1,48 @@
+/** @file
+ Implements UDKFlashUpdate.h
+
+ Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef UDK_FLASH_UPDATE_H_
+#define UDK_FLASH_UPDATE_H_
+
+#include <Uefi.h>
+
+#include <Library/UefiLib.h>
+#include <Library/ShellCEntryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/ShellLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/PcdLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/BaseLib.h>
+#include <Library/TimerLib.h>
+
+#include <Protocol/SimpleFileSystem.h>
+#include <Protocol/Shell.h>
+#include <Protocol/Spi.h>
+#include <Protocol/CpuIo2.h>
+#include <Protocol/SpiCommon.h>
+
+#include "SpiFlashDevice.h"
+
+#define SPI_OPCODE_JEDEC_ID_INDEX 0
+#define SPI_OPCODE_WRITE_S_INDEX 1
+#define SPI_OPCODE_WRITE_INDEX 2
+#define SPI_OPCODE_READ_INDEX 3
+#define SPI_OPCODE_ERASE_INDEX 4
+#define SPI_OPCODE_READ_S_INDEX 5
+#define SPI_OPCODE_CHIP_ERASE_INDEX 6
+#define SPI_OPCODE_READ_SFDP_INDEX 7
+#define SPI_COMMAND_RPMC_OP1_INDEX 8
+#define SPI_COMMAND_RPMC_OP2_INDEX 9
+#define SPI_COMMAND_Enter_4Byte_Addr_INDEX 10
+#define SPI_COMMAND_Exit_4Byte_Addr_INDEX 11
+
+extern SPI_INIT_TABLE mSpiInitTable[];
+extern EFI_RUNTIME_SERVICES *gRT;
+
+#endif
diff --git a/Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Application/UDKFlashUpdate/UDKFlashUpdate.inf b/Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Application/UDKFlashUpdate/UDKFlashUpdate.inf
new file mode 100644
index 0000000000..8f055f3925
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Application/UDKFlashUpdate/UDKFlashUpdate.inf
@@ -0,0 +1,51 @@
+## @file
+# UDK Flash update
+#
+# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010006
+ BASE_NAME = UDKFlashUpdate
+ FILE_GUID = a912f198-7f0e-4803-b908-b757b806ec83
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 0.1
+ ENTRY_POINT = ShellCEntryLib
+
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF
+#
+
+[Sources]
+ UDKFlashUpdate.c
+ UDKFlashUpdate.h
+ SpiFlashDevice.c
+ SpiFlashDevice.h
+
+[Packages]
+ MdePkg/MdePkg.dec
+ ShellPkg/ShellPkg.dec
+ VanGoghCommonPkg/AmdCommonPkg.dec
+ ChachaniBoardPkg/Project.dec
+ MdeModulePkg/MdeModulePkg.dec
+
+[LibraryClasses]
+ UefiLib
+ ShellCEntryLib
+ MemoryAllocationLib
+ ShellLib
+ UefiBootServicesTableLib
+ PcdLib
+ BaseMemoryLib
+ BaseLib
+ TimerLib
+
+[Protocols]
+ gEfiSpiProtocolGuid # CONSUME
+
+[FixedPcd]
+ gPlatformPkgTokenSpaceGuid.PcdFlashAreaSize
+ gPlatformPkgTokenSpaceGuid.PcdFlashAreaBaseAddress
+
--
2.31.1
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#114501): https://edk2.groups.io/g/devel/message/114501
Mute This Topic: https://groups.io/mt/103971398/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-
© 2016 - 2024 Red Hat, Inc.