From: Duke Zhai <duke.z...@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.z...@amd.com>
Cc: Eric Xing <eric.x...@amd.com>
Cc: Ken Yao <ken....@amd.com>
Cc: Igniculus Fu <igniculus...@amd.com>
Cc: Abner Chang <abner.ch...@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/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-


Reply via email to