From: Duke Zhai <duke.z...@amd.com>

BZ #:4640

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           | 679 ++++++++++++++++++

 .../UDKFlashUpdate/UDKFlashUpdate.h           |  48 ++

 .../UDKFlashUpdate/UDKFlashUpdate.inf         |  51 ++

 5 files changed, 877 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..8846eb5381

--- /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..0f3bb149f9

--- /dev/null

+++ 
b/Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Application/UDKFlashUpdate/UDKFlashUpdate.c

@@ -0,0 +1,679 @@

+/** @file

+  Implements UDKFlashUpdate.c

+

+  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>

+  SPDX-License-Identifier: BSD-2-Clause-Patent

+

+**/

+// This file includes code originally published under the following license.

+

+/** @file

+  Platform Flash Access library.

+

+  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..a0904fb863

--- /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 (#114057): https://edk2.groups.io/g/devel/message/114057
Mute This Topic: https://groups.io/mt/103831169/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-



Reply via email to