public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Chang, Abner via groups.io" <abner.chang=amd.com@groups.io>
To: "Zhai, MingXin (Duke)" <duke.zhai@amd.com>,
	"devel@edk2.groups.io" <devel@edk2.groups.io>
Cc: "Xing, Eric" <Eric.Xing@amd.com>, "Fu, Igniculus" <Igniculus.Fu@amd.com>
Subject: Re: [edk2-devel] [PATCH 03/33] AMD/VanGoghBoard: Check in Capsule update
Date: Thu, 25 Jan 2024 11:45:34 +0000	[thread overview]
Message-ID: <LV8PR12MB9452EC9EF68A8B520A6E55DAEA7A2@LV8PR12MB9452.namprd12.prod.outlook.com> (raw)
In-Reply-To: <DS0PR12MB94453E0A1E8E60F045C0D027F67A2@DS0PR12MB9445.namprd12.prod.outlook.com>

[AMD Official Use Only - General]

Hi Duke,
I only got V2 33/33 patch but not the entire patch set. I also didn't see the patch set appears on Group.io.  Could you please check it?

Thanks
Abner

> -----Original Message-----
> From: Zhai, MingXin (Duke) <duke.zhai@amd.com>
> Sent: Thursday, January 25, 2024 4:26 PM
> To: Chang, Abner <Abner.Chang@amd.com>; devel@edk2.groups.io
> Cc: Xing, Eric <Eric.Xing@amd.com>; Fu, Igniculus <Igniculus.Fu@amd.com>
> Subject: RE: [PATCH 03/33] AMD/VanGoghBoard: Check in Capsule update
>
> [AMD Official Use Only - General]
>
> Hi Abner,
>
> Thanks for your review, we have V2 patch improved it:  Remove the old
> tianocore licensing style and redundant license description..
> [PATCH V2 33/33] AMD/VanGoghBoard: Improvement coding style
>
>
> Thanks!
>
>
> -----Original Message-----
> From: Chang, Abner <Abner.Chang@amd.com>
> Sent: Tuesday, January 23, 2024 12:42 PM
> To: Zhai, MingXin (Duke) <duke.zhai@amd.com>; devel@edk2.groups.io
> Cc: Zhai, MingXin (Duke) <duke.zhai@amd.com>; Xing, Eric
> <Eric.Xing@amd.com>; Fu, Igniculus <Igniculus.Fu@amd.com>
> Subject: RE: [PATCH 03/33] AMD/VanGoghBoard: Check in Capsule update
>
> [AMD Official Use Only - General]
>
> I have concern of keeping Intel's old tianocore licensing. I don't see any Intel's
> files those still have the old one. I think we have to remove it and have below
> line above or below AMD's copyright.
> Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
>
> Please also check if Intel updated the copyright year in the original file.
>
> Thanks
> Abner
>
>
> > -----Original Message-----
> > From: duke.zhai@amd.com <duke.zhai@amd.com>
> > Sent: Thursday, January 18, 2024 2:50 PM
> > To: devel@edk2.groups.io
> > Cc: Zhai, MingXin (Duke) <duke.zhai@amd.com>; Xing, Eric
> > <Eric.Xing@amd.com>; Fu, Igniculus <Igniculus.Fu@amd.com>; Chang,
> Abner
> > <Abner.Chang@amd.com>
> > Subject: [PATCH 03/33] AMD/VanGoghBoard: Check in Capsule update
> >
> > From: Duke Zhai <Duke.Zhai@amd.com>
> >
> >
> > BZ #:4640
> >
> > Chachani board supports "Capsule on Disk (CoD)" feature defined in UEFI
> >
> > Spec chapter 8.5.5 "Delivery of Capsules via file on Mass Storage Device".
> >
> > The BIOS capsule image is saved in hard disk as default setting.
> >
> >
> >
> > Signed-off-by: Ken Yao <ken.yao@amd.com>
> >
> > Cc: Duke Zhai <duke.zhai@amd.com>
> >
> > Cc: Eric Xing <eric.xing@amd.com>
> >
> > Cc: Igniculus Fu <igniculus.fu@amd.com>
> >
> > Cc: Abner Chang <abner.chang@amd.com>
> >
> > ---
> >
> >  .../SystemFirmwareDescriptor.aslc             |   99 ++
> >
> >  .../SystemFirmwareDescriptor.inf              |   53 +
> >
> >  .../SystemFirmwareDescriptorPei.c             |   78 ++
> >
> >  .../Include/Library/CapsuleHookLib.h          |   40 +
> >
> >  .../Capsule/CapsuleHookLib/CapsuleHookLib.c   | 1153
> > +++++++++++++++++
> >
> >  .../Capsule/CapsuleHookLib/CapsuleHookLib.inf |   56 +
> >
> >  .../PlatformBootManager.c                     |  803 ++++++++++++
> >
> >  .../PlatformBootManager.h                     |  159 +++
> >
> >  .../PlatformBootManagerLib.inf                |   96 ++
> >
> >  .../PlatformBootManagerLib/PlatformConsole.c  |  504 +++++++
> >
> >  .../PlatformBootManagerLib/PlatformConsole.h  |   78 ++
> >
> >  .../PlatformBootManagerLib/PlatformData.c     |   48 +
> >
> >  .../CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf   |  122 ++
> >
> >  .../CapsuleRuntimeDxe/CapsuleService.c        |  470 +++++++
> >
> >  .../CapsuleRuntimeDxe/CapsuleService.h        |   82 ++
> >
> >  15 files changed, 3841 insertions(+)
> >
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/ChachaniBoardPkg/Capsule/SystemFirmware
> > Descriptor/SystemFirmwareDescriptor.aslc
> >
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/ChachaniBoardPkg/Capsule/SystemFirmware
> > Descriptor/SystemFirmwareDescriptor.inf
> >
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/ChachaniBoardPkg/Capsule/SystemFirmware
> > Descriptor/SystemFirmwareDescriptorPei.c
> >
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/ChachaniBoardPkg/Include/Library/CapsuleH
> > ookLib.h
> >
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/ChachaniBoardPkg/Library/Capsule/CapsuleH
> > ookLib/CapsuleHookLib.c
> >
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/ChachaniBoardPkg/Library/Capsule/CapsuleH
> > ookLib/CapsuleHookLib.inf
> >
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/ChachaniBoardPkg/Library/Capsule/Platform
> > BootManagerLib/PlatformBootManager.c
> >
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/ChachaniBoardPkg/Library/Capsule/Platform
> > BootManagerLib/PlatformBootManager.h
> >
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/ChachaniBoardPkg/Library/Capsule/Platform
> > BootManagerLib/PlatformBootManagerLib.inf
> >
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/ChachaniBoardPkg/Library/Capsule/Platform
> > BootManagerLib/PlatformConsole.c
> >
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/ChachaniBoardPkg/Library/Capsule/Platform
> > BootManagerLib/PlatformConsole.h
> >
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/ChachaniBoardPkg/Library/Capsule/Platform
> > BootManagerLib/PlatformData.c
> >
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/MdeModulePkg/Universal/Ca
> > psuleRuntimeDxe/CapsuleRuntimeDxe.inf
> >
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/MdeModulePkg/Universal/Ca
> > psuleRuntimeDxe/CapsuleService.c
> >
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/MdeModulePkg/Universal/Ca
> > psuleRuntimeDxe/CapsuleService.h
> >
> >
> >
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/ChachaniBoardPkg/Capsule/SystemFirmwa
> > reDescriptor/SystemFirmwareDescriptor.aslc
> >
> b/Platform/AMD/VanGoghBoard/ChachaniBoardPkg/Capsule/SystemFirmwa
> > reDescriptor/SystemFirmwareDescriptor.aslc
> >
> > new file mode 100644
> >
> > index 0000000000..af73e846fc
> >
> > --- /dev/null
> >
> > +++
> >
> b/Platform/AMD/VanGoghBoard/ChachaniBoardPkg/Capsule/SystemFirmwa
> > reDescriptor/SystemFirmwareDescriptor.aslc
> >
> > @@ -0,0 +1,99 @@
> >
> > +/** @file
> >
> > +  System firmware Descriptor file
> >
> > +
> >
> > +  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
> >
> > +  System Firmware descriptor.
> >
> > +
> >
> > +  Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
> >
> > +  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 <PiPei.h>
> >
> > +#include <Protocol/FirmwareManagement.h>
> >
> > +#include <Guid/EdkiiSystemFmpCapsule.h>
> >
> > +
> >
> > +#define PACKAGE_VERSION                     0xFFFFFFFF
> >
> > +#define PACKAGE_VERSION_STRING              L"Unknown"
> >
> > +
> >
> > +#define CURRENT_FIRMWARE_VERSION            0x00003818
> >
> > +#define CURRENT_FIRMWARE_VERSION_STRING     L"00003818"
> >
> > +#define LOWEST_SUPPORTED_FIRMWARE_VERSION   0x00000001
> >
> > +
> >
> > +#define IMAGE_ID                            SIGNATURE_64('C', 'H', 'A', 'C', 'H',
> 'A','N','I')
> >
> > +#define IMAGE_ID_STRING                     L"ChachaniFD"
> >
> > +
> >
> > +// PcdSystemFmpCapsuleImageTypeIdGuid
> >
> > +#define IMAGE_TYPE_ID_GUID                  { 0x38663fe6, 0x934f, 0x42a1,
> > { 0xbc, 0xb0, 0xf7, 0x9e, 0x62, 0xec, 0xbe, 0x80 } }
> >
> > +
> >
> > +typedef struct {
> >
> > +  EDKII_SYSTEM_FIRMWARE_IMAGE_DESCRIPTOR  Descriptor;
> >
> > +  // real string data
> >
> > +  CHAR16
> > ImageIdNameStr[sizeof(IMAGE_ID_STRING)/sizeof(CHAR16)];
> >
> > +  CHAR16
> >
> VersionNameStr[sizeof(CURRENT_FIRMWARE_VERSION_STRING)/sizeof(CHA
> > R16)];
> >
> > +  CHAR16
> >
> PackageVersionNameStr[sizeof(PACKAGE_VERSION_STRING)/sizeof(CHAR16)
> > ];
> >
> > +} IMAGE_DESCRIPTOR;
> >
> > +
> >
> > +IMAGE_DESCRIPTOR mImageDescriptor =
> >
> > +{
> >
> > +  {
> >
> > +    EDKII_SYSTEM_FIRMWARE_IMAGE_DESCRIPTOR_SIGNATURE,
> >
> > +    sizeof(EDKII_SYSTEM_FIRMWARE_IMAGE_DESCRIPTOR),
> >
> > +    sizeof(IMAGE_DESCRIPTOR),
> >
> > +    PACKAGE_VERSION,                                       // PackageVersion
> >
> > +    OFFSET_OF (IMAGE_DESCRIPTOR, PackageVersionNameStr),   //
> > PackageVersionName
> >
> > +    1,                                                     // ImageIndex;
> >
> > +    {0x0},                                                 // Reserved
> >
> > +    IMAGE_TYPE_ID_GUID,                                    // ImageTypeId;
> >
> > +    IMAGE_ID,                                              // ImageId;
> >
> > +    OFFSET_OF (IMAGE_DESCRIPTOR, ImageIdNameStr),          //
> > ImageIdName;
> >
> > +    CURRENT_FIRMWARE_VERSION,                              // Version;
> >
> > +    OFFSET_OF (IMAGE_DESCRIPTOR, VersionNameStr),          //
> VersionName;
> >
> > +    {0x0},                                                 // Reserved2
> >
> > +    FixedPcdGet32(PcdFlashAreaSize),                       // Size;
> >
> > +    IMAGE_ATTRIBUTE_IMAGE_UPDATABLE |
> >
> > +      IMAGE_ATTRIBUTE_RESET_REQUIRED |
> >
> > +      IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED |
> >
> > +      IMAGE_ATTRIBUTE_IN_USE,                              // AttributesSupported;
> >
> > +    IMAGE_ATTRIBUTE_IMAGE_UPDATABLE |
> >
> > +      IMAGE_ATTRIBUTE_RESET_REQUIRED |
> >
> > +      IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED |
> >
> > +      IMAGE_ATTRIBUTE_IN_USE,                              // AttributesSetting;
> >
> > +    0x0,                                                   // Compatibilities;
> >
> > +    LOWEST_SUPPORTED_FIRMWARE_VERSION,                     //
> > LowestSupportedImageVersion;
> >
> > +    0x00000000,                                            // LastAttemptVersion;
> >
> > +    0,                                                     // LastAttemptStatus;
> >
> > +    {0x0},                                                 // Reserved3
> >
> > +    0,                                                     // HardwareInstance;
> >
> > +  },
> >
> > +  // real string data
> >
> > +  {IMAGE_ID_STRING},
> >
> > +  {CURRENT_FIRMWARE_VERSION_STRING},
> >
> > +  {PACKAGE_VERSION_STRING},
> >
> > +};
> >
> > +
> >
> > +
> >
> > +VOID*
> >
> > +ReferenceAcpiTable (
> >
> > +  VOID
> >
> > +  )
> >
> > +{
> >
> > +  //
> >
> > +  // Reference the table being generated to prevent the optimizer from
> >
> > +  // removing the data structure from the executable
> >
> > +  //
> >
> > +  return (VOID*)&mImageDescriptor;
> >
> > +}
> >
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/ChachaniBoardPkg/Capsule/SystemFirmwa
> > reDescriptor/SystemFirmwareDescriptor.inf
> >
> b/Platform/AMD/VanGoghBoard/ChachaniBoardPkg/Capsule/SystemFirmwa
> > reDescriptor/SystemFirmwareDescriptor.inf
> >
> > new file mode 100644
> >
> > index 0000000000..28d0b8f644
> >
> > --- /dev/null
> >
> > +++
> >
> b/Platform/AMD/VanGoghBoard/ChachaniBoardPkg/Capsule/SystemFirmwa
> > reDescriptor/SystemFirmwareDescriptor.inf
> >
> > @@ -0,0 +1,53 @@
> >
> > +## @file
> >
> > +#  System firmware descriptor INF file
> >
> > +#
> >
> > +# 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
> >
> > +#  System Firmware descriptor.
> >
> > +#
> >
> > +#  Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
> >
> > +#  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.
> >
> > +#
> >
> > +##
> >
> > +
> >
> > +[Defines]
> >
> > +  INF_VERSION                    = 0x00010005
> >
> > +  BASE_NAME                      = SystemFirmwareDescriptor
> >
> > +  FILE_GUID                      = 90B2B846-CA6D-4D6E-A8D3-C140A8E110AC
> >
> > +  MODULE_TYPE                    = PEIM
> >
> > +  VERSION_STRING                 = 1.0
> >
> > +  ENTRY_POINT                    = SystemFirmwareDescriptorPeimEntry
> >
> > +
> >
> > +[Sources]
> >
> > +  SystemFirmwareDescriptorPei.c
> >
> > +  SystemFirmwareDescriptor.aslc
> >
> > +
> >
> > +[Packages]
> >
> > +  MdePkg/MdePkg.dec
> >
> > +  MdeModulePkg/MdeModulePkg.dec
> >
> > +  SignedCapsulePkg/SignedCapsulePkg.dec
> >
> > +  ChachaniBoardPkg/Project.dec
> >
> > +
> >
> > +[LibraryClasses]
> >
> > +  PcdLib
> >
> > +  PeiServicesLib
> >
> > +  DebugLib
> >
> > +  PeimEntryPoint
> >
> > +
> >
> > +[Pcd]
> >
> > +
> >
> gEfiSignedCapsulePkgTokenSpaceGuid.PcdEdkiiSystemFirmwareImageDescript
> > or
> >
> > +  gPlatformPkgTokenSpaceGuid.PcdFlashAreaSize
> >
> > +
> >
> > +[Depex]
> >
> > +  TRUE
> >
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/ChachaniBoardPkg/Capsule/SystemFirmwa
> > reDescriptor/SystemFirmwareDescriptorPei.c
> >
> b/Platform/AMD/VanGoghBoard/ChachaniBoardPkg/Capsule/SystemFirmwa
> > reDescriptor/SystemFirmwareDescriptorPei.c
> >
> > new file mode 100644
> >
> > index 0000000000..2413854577
> >
> > --- /dev/null
> >
> > +++
> >
> b/Platform/AMD/VanGoghBoard/ChachaniBoardPkg/Capsule/SystemFirmwa
> > reDescriptor/SystemFirmwareDescriptorPei.c
> >
> > @@ -0,0 +1,78 @@
> >
> > +/** @file
> >
> > +  Implements SystemFirmwareDescriptorPei.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
> >
> > +  System Firmware descriptor producer.
> >
> > +
> >
> > +  Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
> >
> > +  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 <PiPei.h>
> >
> > +#include <Library/PcdLib.h>
> >
> > +#include <Library/PeiServicesLib.h>
> >
> > +#include <Library/DebugLib.h>
> >
> > +#include <Protocol/FirmwareManagement.h>
> >
> > +#include <Guid/EdkiiSystemFmpCapsule.h>
> >
> > +
> >
> > +/**
> >
> > +  Entrypoint for SystemFirmwareDescriptor PEIM.
> >
> > +
> >
> > +  @param[in]  FileHandle  Handle of the file being invoked.
> >
> > +  @param[in]  PeiServices Describes the list of possible PEI Services.
> >
> > +
> >
> > +  @retval EFI_SUCCESS            PPI successfully installed.
> >
> > +**/
> >
> > +EFI_STATUS
> >
> > +EFIAPI
> >
> > +SystemFirmwareDescriptorPeimEntry (
> >
> > +  IN EFI_PEI_FILE_HANDLE     FileHandle,
> >
> > +  IN CONST EFI_PEI_SERVICES  **PeiServices
> >
> > +  )
> >
> > +{
> >
> > +  EFI_STATUS                              Status;
> >
> > +  EDKII_SYSTEM_FIRMWARE_IMAGE_DESCRIPTOR  *Descriptor;
> >
> > +  UINTN                                   Size;
> >
> > +  UINTN                                   Index;
> >
> > +  UINT32                                  AuthenticationStatus;
> >
> > +
> >
> > +  //
> >
> > +  // Search RAW section.
> >
> > +  //
> >
> > +  Index = 0;
> >
> > +  while (TRUE) {
> >
> > +    Status = PeiServicesFfsFindSectionData3 (EFI_SECTION_RAW, Index,
> > FileHandle, (VOID **)&Descriptor, &AuthenticationStatus);
> >
> > +    if (EFI_ERROR (Status)) {
> >
> > +      // Should not happen, must something wrong in FDF.
> >
> > +      ASSERT (FALSE);
> >
> > +      return EFI_NOT_FOUND;
> >
> > +    }
> >
> > +
> >
> > +    if (Descriptor->Signature ==
> > EDKII_SYSTEM_FIRMWARE_IMAGE_DESCRIPTOR_SIGNATURE) {
> >
> > +      break;
> >
> > +    }
> >
> > +
> >
> > +    Index++;
> >
> > +  }
> >
> > +
> >
> > +  DEBUG ((DEBUG_INFO, "EDKII_SYSTEM_FIRMWARE_IMAGE_DESCRIPTOR
> > size - 0x%x\n", Descriptor->Length));
> >
> > +
> >
> > +  Size = Descriptor->Length;
> >
> > +  PcdSetPtrS (PcdEdkiiSystemFirmwareImageDescriptor, &Size, Descriptor);
> >
> > +
> >
> > +  return EFI_SUCCESS;
> >
> > +}
> >
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/ChachaniBoardPkg/Include/Library/Capsule
> > HookLib.h
> >
> b/Platform/AMD/VanGoghBoard/ChachaniBoardPkg/Include/Library/Capsule
> > HookLib.h
> >
> > new file mode 100644
> >
> > index 0000000000..e573ac0f09
> >
> > --- /dev/null
> >
> > +++
> >
> b/Platform/AMD/VanGoghBoard/ChachaniBoardPkg/Include/Library/Capsule
> > HookLib.h
> >
> > @@ -0,0 +1,40 @@
> >
> > +/** @file
> >
> > +  Implements CapsuleHookLib.h
> >
> > +
> >
> > +  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
> >
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> >
> > +
> >
> > +**/
> >
> > +
> >
> > +#ifndef _CAPSULE_HOOK_LIB_H_
> >
> > +#define _CAPSULE_HOOK_LIB_H_
> >
> > +
> >
> > +/**
> >
> > +  Detect Capsule file from ESP partition and update capsule.
> >
> > +
> >
> > +  @retval EFI_SUCCESS.              Opertion is successful.
> >
> > +  @retval EFI_OUT_OF_RESOURCES      No enough buffer to allocate.
> >
> > +  @retval EFI_ERROR                 Internal error when update Capsule.
> >
> > +
> >
> > +**/
> >
> > +EFI_STATUS
> >
> > +EFIAPI
> >
> > +CapsuleUpdateViaFileHook (
> >
> > +  VOID
> >
> > +  );
> >
> > +
> >
> > +/**
> >
> > +  Detect Capsule file from ESP partition and update capsule.
> >
> > +
> >
> > +  @retval EFI_SUCCESS.              Opertion is successful.
> >
> > +  @retval EFI_OUT_OF_RESOURCES      No enough buffer to allocate.
> >
> > +  @retval EFI_ERROR                 Internal error when update Capsule.
> >
> > +
> >
> > +**/
> >
> > +EFI_STATUS
> >
> > +EFIAPI
> >
> > +CapsuleUpdateViaFileLib (
> >
> > +  VOID
> >
> > +  );
> >
> > +
> >
> > +#endif
> >
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/ChachaniBoardPkg/Library/Capsule/Capsul
> > eHookLib/CapsuleHookLib.c
> >
> b/Platform/AMD/VanGoghBoard/ChachaniBoardPkg/Library/Capsule/Capsul
> > eHookLib/CapsuleHookLib.c
> >
> > new file mode 100644
> >
> > index 0000000000..b4513514b8
> >
> > --- /dev/null
> >
> > +++
> >
> b/Platform/AMD/VanGoghBoard/ChachaniBoardPkg/Library/Capsule/Capsul
> > eHookLib/CapsuleHookLib.c
> >
> > @@ -0,0 +1,1153 @@
> >
> > +/** @file
> >
> > +  Implements CapsuleHookLib.c
> >
> > +
> >
> > +  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
> >
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> >
> > +
> >
> > +**/
> >
> > +
> >
> > +#include <Uefi.h>
> >
> > +#include <PiDxe.h>
> >
> > +#include <Guid/Gpt.h>
> >
> > +#include <Guid/FileSystemInfo.h>
> >
> > +#include <Protocol/SimpleFileSystem.h>
> >
> > +#include <Protocol/BlockIo.h>
> >
> > +#include <Library/DebugLib.h>
> >
> > +#include <Library/BaseLib.h>
> >
> > +#include <Library/UefiBootServicesTableLib.h>
> >
> > +#include <Library/UefiRuntimeServicesTableLib.h>
> >
> > +#include <Library/BaseMemoryLib.h>
> >
> > +#include <Library/MemoryAllocationLib.h>
> >
> > +#include <Library/FileHandleLib.h>
> >
> > +#include <Library/DevicePathLib.h>
> >
> > +#include <Library/CapsuleLib.h>
> >
> > +#include <Library/CapsuleHookLib.h>
> >
> > +#include <OtaCapsuleUpdate.h>
> >
> > +
> >
> > +#define CAP_FILE_NAME  (CHAR16 *) FixedPcdGetPtr
> (PcdOtaCapsuleName)
> >
> > +#define CAP_PARTITION  (CHAR16 *) FixedPcdGetPtr
> > (PcdOtaCapsulePartitionName)
> >
> > +CHAR16                    mPartitionName[36];
> >
> > +STATIC CONST CHAR16       *mSlotSuffixes[2] = { L"_a", L"_b" };
> >
> > +EFI_DEVICE_PATH_PROTOCOL  *mBootDevicePath;
> >
> > +
> >
> > +#define FLASH_DEVICE_PATH_SIZE(DevPath)  (GetDevicePathSize (DevPath)
> -
> > sizeof (EFI_DEVICE_PATH_PROTOCOL))
> >
> > +
> >
> > +// Hidden (Not exported) function from DxeCapsuleReportLib.
> >
> > +extern
> >
> > +EFI_STATUS
> >
> > +// Not EFIAPI!
> >
> > +RecordCapsuleStatusVariable (
> >
> > +  IN EFI_CAPSULE_HEADER  *CapsuleHeader,
> >
> > +  IN EFI_STATUS          CapsuleStatus
> >
> > +  );
> >
> > +
> >
> > +/**
> >
> > +  Read GPT partition entries.
> >
> > +
> >
> > +  @param[in]  BlockIo             The BlockIo of device.
> >
> > +  @param[out] PartitionEntries    The output buffer of partition entry.
> >
> > +
> >
> > +  @retval EFI_SUCCESS             Operation completed successfully.
> >
> > +  @retval others                  Some error occurs when executing this routine.
> >
> > +
> >
> > +**/
> >
> > +EFI_STATUS
> >
> > +EFIAPI
> >
> > +ReadPartitionEntries (
> >
> > +  IN EFI_BLOCK_IO_PROTOCOL  *BlockIo,
> >
> > +  OUT EFI_PARTITION_ENTRY   **PartitionEntries
> >
> > +  )
> >
> > +{
> >
> > +  EFI_STATUS                  Status;
> >
> > +  UINTN                       EntrySize;
> >
> > +  UINTN                       NumEntries;
> >
> > +  UINTN                       BufferSize;
> >
> > +  UINT32                      MediaId;
> >
> > +  EFI_PARTITION_TABLE_HEADER  *GptHeader;
> >
> > +
> >
> > +  MediaId = BlockIo->Media->MediaId;
> >
> > +
> >
> > +  //
> >
> > +  // Read size of Partition entry and number of entries from GPT header
> >
> > +  //
> >
> > +  GptHeader = AllocatePool (BlockIo->Media->BlockSize);
> >
> > +  if (GptHeader == NULL) {
> >
> > +    return EFI_OUT_OF_RESOURCES;
> >
> > +  }
> >
> > +
> >
> > +  Status = BlockIo->ReadBlocks (
> >
> > +                      BlockIo,
> >
> > +                      MediaId,
> >
> > +                      PRIMARY_PART_HEADER_LBA,
> >
> > +                      BlockIo->Media->BlockSize,
> >
> > +                      (VOID *)GptHeader
> >
> > +                      );
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    FreePool (GptHeader);
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  //
> >
> > +  // Check there is a GPT on the media
> >
> > +  //
> >
> > +  if ((GptHeader->Header.Signature != EFI_PTAB_HEADER_ID) ||
> (GptHeader-
> > >MyLBA != PRIMARY_PART_HEADER_LBA)) {
> >
> > +    DEBUG ((DEBUG_ERROR, "No valid GPT found!\n"));
> >
> > +    FreePool (GptHeader);
> >
> > +    return EFI_DEVICE_ERROR;
> >
> > +  }
> >
> > +
> >
> > +  EntrySize  = GptHeader->SizeOfPartitionEntry;
> >
> > +  NumEntries = GptHeader->NumberOfPartitionEntries;
> >
> > +  if ((EntrySize == 0) || (NumEntries == 0)) {
> >
> > +    DEBUG ((DEBUG_ERROR, "Invalid Entry size or number.\n"));
> >
> > +    return EFI_DEVICE_ERROR;
> >
> > +  }
> >
> > +
> >
> > +  FreePool (GptHeader);
> >
> > +
> >
> > +  BufferSize        = ALIGN_VALUE (EntrySize * NumEntries, BlockIo->Media-
> > >BlockSize);
> >
> > +  *PartitionEntries = AllocatePool (BufferSize);
> >
> > +  if (PartitionEntries == NULL) {
> >
> > +    return EFI_OUT_OF_RESOURCES;
> >
> > +  }
> >
> > +
> >
> > +  Status = BlockIo->ReadBlocks (
> >
> > +                      BlockIo,
> >
> > +                      MediaId,
> >
> > +                      2,
> >
> > +                      BufferSize,
> >
> > +                      (VOID *)*PartitionEntries
> >
> > +                      );
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    FreePool (*PartitionEntries);
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  return Status;
> >
> > +}
> >
> > +
> >
> > +/**
> >
> > +  Get capsule partition device path by partition name.
> >
> > +
> >
> > +  @param[in]  BootDevicePath      Pointer to the Device Path Protocol from
> > variable.
> >
> > +  @param[in]  PartitionName       The given partition name.
> >
> > +  @param[out] PartitionDevicePath Pointer to the Device Path Protocol of
> > capsule partition.
> >
> > +
> >
> > +  @retval EFI_SUCCESS             Operation completed successfully.
> >
> > +  @retval others                  Some error occurs when executing this routine.
> >
> > +
> >
> > +**/
> >
> > +EFI_STATUS
> >
> > +EFIAPI
> >
> > +GetDevicePathByName (
> >
> > +  IN  EFI_DEVICE_PATH_PROTOCOL  *BootDevicePath,
> >
> > +  IN  CONST CHAR16              *PartitionName,
> >
> > +  OUT EFI_DEVICE_PATH_PROTOCOL  **PartitionDevicePath
> >
> > +  )
> >
> > +{
> >
> > +  EFI_STATUS                Status;
> >
> > +  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
> >
> > +  EFI_BLOCK_IO_PROTOCOL     *BlockIo;
> >
> > +  EFI_DEVICE_PATH_PROTOCOL  *NextNode;
> >
> > +  HARDDRIVE_DEVICE_PATH     *PartitionNode;
> >
> > +  EFI_PARTITION_ENTRY       *PartitionEntries;
> >
> > +  UINTN                     NumHandles;
> >
> > +  UINTN                     LoopIndex;
> >
> > +  EFI_HANDLE                *AllHandles;
> >
> > +  EFI_HANDLE                Handle;
> >
> > +
> >
> > +  //
> >
> > +  // Get all BlockIo handles in system
> >
> > +  //
> >
> > +  Status = gBS->LocateHandleBuffer (
> >
> > +                  ByProtocol,
> >
> > +                  &gEfiBlockIoProtocolGuid,
> >
> > +                  NULL,
> >
> > +                  &NumHandles,
> >
> > +                  &AllHandles
> >
> > +                  );
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    DEBUG ((DEBUG_ERROR, "Couldn't locate BlockIo protocol: %r\n",
> > Status));
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  for (LoopIndex = 0; LoopIndex < NumHandles; LoopIndex++) {
> >
> > +    Status = gBS->OpenProtocol (
> >
> > +                    AllHandles[LoopIndex],
> >
> > +                    &gEfiDevicePathProtocolGuid,
> >
> > +                    (VOID **)&DevicePath,
> >
> > +                    gImageHandle,
> >
> > +                    NULL,
> >
> > +                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
> >
> > +                    );
> >
> > +    if (EFI_ERROR (Status)) {
> >
> > +      DEBUG ((DEBUG_ERROR, "Couldn't locate DevicePath protocol: %r\n",
> > Status));
> >
> > +      return Status;
> >
> > +    }
> >
> > +
> >
> > +    if (!CompareMem (DevicePath, BootDevicePath,
> FLASH_DEVICE_PATH_SIZE
> > (BootDevicePath))) {
> >
> > +      BootDevicePath = DevicePath;
> >
> > +      break;
> >
> > +    }
> >
> > +  }
> >
> > +
> >
> > +  DevicePath = BootDevicePath;
> >
> > +  Status     = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid,
> &DevicePath,
> > &Handle);
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    DEBUG ((DEBUG_ERROR, "Couldn't locate device status: %r\n", Status));
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  Status = gBS->OpenProtocol (
> >
> > +                  Handle,
> >
> > +                  &gEfiBlockIoProtocolGuid,
> >
> > +                  (VOID **)&BlockIo,
> >
> > +                  gImageHandle,
> >
> > +                  NULL,
> >
> > +                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
> >
> > +                  );
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    DEBUG ((DEBUG_ERROR, "Failed to get BlockIo: %r\n", Status));
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  Status = ReadPartitionEntries (BlockIo, &PartitionEntries);
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    DEBUG ((DEBUG_ERROR, "Failed to read partitions from disk device:
> %r\n",
> > Status));
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  for (LoopIndex = 0; LoopIndex < NumHandles; LoopIndex++) {
> >
> > +    Status = gBS->OpenProtocol (
> >
> > +                    AllHandles[LoopIndex],
> >
> > +                    &gEfiDevicePathProtocolGuid,
> >
> > +                    (VOID **)&DevicePath,
> >
> > +                    gImageHandle,
> >
> > +                    NULL,
> >
> > +                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
> >
> > +                    );
> >
> > +    if (EFI_ERROR (Status)) {
> >
> > +      DEBUG ((DEBUG_ERROR, "Couldn't locate DevicePath protocol: %r\n",
> > Status));
> >
> > +      return Status;
> >
> > +    }
> >
> > +
> >
> > +    if (!CompareMem (DevicePath, BootDevicePath,
> FLASH_DEVICE_PATH_SIZE
> > (BootDevicePath))) {
> >
> > +      NextNode = NextDevicePathNode (DevicePath);
> >
> > +
> >
> > +      while (!IsDevicePathEndType (NextNode)) {
> >
> > +        if ((NextNode->Type == MEDIA_DEVICE_PATH) &&
> >
> > +            (NextNode->SubType == MEDIA_HARDDRIVE_DP))
> >
> > +        {
> >
> > +          break;
> >
> > +        }
> >
> > +
> >
> > +        NextNode = NextDevicePathNode (NextNode);
> >
> > +      }
> >
> > +
> >
> > +      if (IsDevicePathEndType (NextNode)) {
> >
> > +        continue;
> >
> > +      }
> >
> > +
> >
> > +      PartitionNode = (HARDDRIVE_DEVICE_PATH *)NextNode;
> >
> > +
> >
> > +      if (PartitionNode->PartitionNumber == 0) {
> >
> > +        continue;
> >
> > +      }
> >
> > +
> >
> > +      if (0 == StrCmp (PartitionEntries[PartitionNode->PartitionNumber -
> > 1].PartitionName, PartitionName)) {
> >
> > +        break;
> >
> > +      }
> >
> > +    }
> >
> > +  }
> >
> > +
> >
> > +  if (LoopIndex >= NumHandles) {
> >
> > +    return EFI_LOAD_ERROR;
> >
> > +  }
> >
> > +
> >
> > +  *PartitionDevicePath = DevicePath;
> >
> > +
> >
> > +  return EFI_SUCCESS;
> >
> > +}
> >
> > +
> >
> > +/**
> >
> > +  Get capsule paritioin information.
> >
> > +
> >
> > +  @param[in]  VOID
> >
> > +
> >
> > +  @retval EFI_SUCCESS             Operation completed successfully.
> >
> > +  @retval others                  Some error occurs when executing this routine.
> >
> > +
> >
> > +**/
> >
> > +EFI_STATUS
> >
> > +EFIAPI
> >
> > +CapsulePartitionInfo (
> >
> > +  VOID
> >
> > +  )
> >
> > +{
> >
> > +  EFI_STATUS          Status;
> >
> > +  UINTN               VarSize;
> >
> > +  OTA_CAPSULE_UPDATE  OtaCapsuleUpdateVal;
> >
> > +  CHAR16              BootPath[512];
> >
> > +
> >
> > +  //
> >
> > +  // Get Capsule A/B partition.
> >
> > +  //
> >
> > +  ZeroMem (&OtaCapsuleUpdateVal, sizeof (OTA_CAPSULE_UPDATE));
> >
> > +  VarSize = sizeof (OTA_CAPSULE_UPDATE);
> >
> > +  Status  = gRT->GetVariable (
> >
> > +                   OTA_CAPSULE_VAR_NAME,
> >
> > +                   &gOtaCapsuleUpdateGuid,
> >
> > +                   NULL,
> >
> > +                   &VarSize,
> >
> > +                   (VOID *)&OtaCapsuleUpdateVal
> >
> > +                   );
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    DEBUG ((DEBUG_ERROR, "CapsulePartitionInfo: GetVariable failed: %r\n",
> > Status));
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  ZeroMem (mPartitionName, sizeof (mPartitionName));
> >
> > +  StrCpyS (mPartitionName, sizeof (mPartitionName), CAP_PARTITION);
> >
> > +  StrCatS (mPartitionName, sizeof (mPartitionName),
> > mSlotSuffixes[OtaCapsuleUpdateVal.UpdateSlot]);
> >
> > +  DEBUG ((DEBUG_INFO, "CapsulePartitionInfo from partition: %s\n",
> > mPartitionName));
> >
> > +
> >
> > +  //
> >
> > +  // Get Boot device path
> >
> > +  //
> >
> > +  VarSize = 512;
> >
> > +  Status  = gRT->GetVariable (
> >
> > +                   L"AndroidBootDevice",
> >
> > +                   &gEfiGlobalVariableGuid,
> >
> > +                   NULL,
> >
> > +                   &VarSize,
> >
> > +                   BootPath
> >
> > +                   );
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    DEBUG ((DEBUG_ERROR, "CapsulePartitionInfo: Get BootDevice variable
> > failed: %r\n", Status));
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  mBootDevicePath = ConvertTextToDevicePath (BootPath);
> >
> > +  if (mBootDevicePath == NULL) {
> >
> > +    DEBUG ((DEBUG_ERROR, "mBootDevicePath is NULL\n"));
> >
> > +    return EFI_NOT_FOUND;
> >
> > +  }
> >
> > +
> >
> > +  return EFI_SUCCESS;
> >
> > +}
> >
> > +
> >
> > +/**
> >
> > +  Read Capsule file information from FAT partiton.
> >
> > +
> >
> > +  @param[in]  FileName              File name of Capsule binary
> >
> > +  @param[out] Buffer                Return buffer pointer of Capsule binary
> >
> > +  @param[out] BufferSize            Capsule binary size
> >
> > +
> >
> > +  @retval EFI_SUCCESS               Read Capsule information successfully
> >
> > +  @retval EFI_OUT_OF_RESOURCES      No enough buffer to allocate
> >
> > +  @retval EFI_NOT_FOUND             Fail to read Capsule information
> >
> > +  @retval Others                    Internal error when read Capsule information
> >
> > +
> >
> > +**/
> >
> > +EFI_STATUS
> >
> > +EFIAPI
> >
> > +ReadCapsuleInfo (
> >
> > +  IN CHAR16  *FileName,
> >
> > +  OUT VOID   **Buffer,
> >
> > +  OUT UINTN  *BufferSize
> >
> > +  )
> >
> > +{
> >
> > +  EFI_STATUS                       Status;
> >
> > +  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL  *Fs;
> >
> > +  EFI_FILE                         *Root;
> >
> > +  EFI_FILE                         *FileHandle;
> >
> > +  UINT8                            *FileBuffer;
> >
> > +  UINTN                            FileSize;
> >
> > +  EFI_HANDLE                       Handle;
> >
> > +  EFI_BLOCK_IO_PROTOCOL            *BlockIo;
> >
> > +  EFI_DEVICE_PATH_PROTOCOL         *BootPartitionPath;
> >
> > +
> >
> > +  FileBuffer = NULL;
> >
> > +  FileSize   = 0;
> >
> > +
> >
> > +  DEBUG ((DEBUG_INFO, "ReadCapsuleInfo()...\n"));
> >
> > +
> >
> > +  Status = GetDevicePathByName (mBootDevicePath, mPartitionName,
> > &BootPartitionPath);
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    DEBUG ((DEBUG_ERROR, "GetDevicePathByName failed: %r\n", Status));
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid,
> > &BootPartitionPath, &Handle);
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    DEBUG ((DEBUG_ERROR, "ReadCapsuleInfo: Locate DevicePath failed:
> > %r\n", Status));
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  //
> >
> > +  // Get Capsule file
> >
> > +  //
> >
> > +  Status = gBS->HandleProtocol (Handle, &gEfiBlockIoProtocolGuid, (VOID
> > **)&BlockIo);
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  if (BlockIo->Media->RemovableMedia) {
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  Status = gBS->HandleProtocol (Handle,
> &gEfiSimpleFileSystemProtocolGuid,
> > (VOID **)&Fs);
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  Status = Fs->OpenVolume (Fs, &Root);
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  Status = Root->Open (Root, &FileHandle, FileName,
> EFI_FILE_MODE_READ,
> > 0);
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  if (FileHandle == NULL) {
> >
> > +    return EFI_NOT_FOUND;
> >
> > +  }
> >
> > +
> >
> > +  Status = FileHandleGetSize (FileHandle, (UINT64 *)&FileSize);
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    FileHandleClose (FileHandle);
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  FileBuffer = AllocateZeroPool (FileSize);
> >
> > +  if (FileBuffer == NULL) {
> >
> > +    FileHandleClose (FileHandle);
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  Status = FileHandleRead (FileHandle, &FileSize, FileBuffer);
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    FileHandleClose (FileHandle);
> >
> > +    FreePool (FileBuffer);
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  Status = FileHandleClose (FileHandle);
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    FreePool (FileBuffer);
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  *Buffer     = FileBuffer;
> >
> > +  *BufferSize = FileSize;
> >
> > +
> >
> > +  DEBUG ((DEBUG_INFO, "Capsule size: 0x%x\n", *BufferSize));
> >
> > +
> >
> > +  return EFI_SUCCESS;
> >
> > +}
> >
> > +
> >
> > +/**
> >
> > +  Remove capsule file from FAT partitions.
> >
> > +
> >
> > +  @param[in]  FileName              File name of Capsule binary
> >
> > +
> >
> > +  @retval EFI_SUCCESS               Delete capsule succesfully
> >
> > +  @retval Others                    Internal error of delete capsule function
> >
> > +
> >
> > +**/
> >
> > +EFI_STATUS
> >
> > +EFIAPI
> >
> > +RemoveCapsuleFile (
> >
> > +  IN CHAR16  *FileName
> >
> > +  )
> >
> > +{
> >
> > +  EFI_STATUS                       Status;
> >
> > +  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL  *Fs;
> >
> > +  EFI_FILE                         *Root;
> >
> > +  EFI_FILE                         *FileHandle;
> >
> > +  EFI_HANDLE                       Handle;
> >
> > +  EFI_BLOCK_IO_PROTOCOL            *BlockIo;
> >
> > +  EFI_DEVICE_PATH_PROTOCOL         *BootPartitionPath;
> >
> > +
> >
> > +  DEBUG ((DEBUG_INFO, "RemoveCapsuleFile()...\n"));
> >
> > +
> >
> > +  Status = GetDevicePathByName (mBootDevicePath, mPartitionName,
> > &BootPartitionPath);
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    DEBUG ((DEBUG_ERROR, "GetDevicePathByName failed: %r\n", Status));
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid,
> > &BootPartitionPath, &Handle);
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    DEBUG ((DEBUG_ERROR, "ReadCapsuleInfo: Locate DevicePath failed:
> > %r\n", Status));
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  //
> >
> > +  // Remove Capsule file
> >
> > +  //
> >
> > +  Status = gBS->HandleProtocol (Handle, &gEfiBlockIoProtocolGuid, (VOID
> > **)&BlockIo);
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  if (BlockIo->Media->RemovableMedia) {
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  Status = gBS->HandleProtocol (Handle,
> &gEfiSimpleFileSystemProtocolGuid,
> > (VOID **)&Fs);
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  Status = Fs->OpenVolume (Fs, &Root);
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  Status = Root->Open (Root, &FileHandle, FileName, EFI_FILE_MODE_READ
> |
> > EFI_FILE_MODE_WRITE, 0);
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  if (FileHandle == NULL) {
> >
> > +    return EFI_NOT_FOUND;
> >
> > +  }
> >
> > +
> >
> > +  Status = FileHandleDelete (FileHandle);
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  return EFI_SUCCESS;
> >
> > +}
> >
> > +
> >
> > +/**
> >
> > +  Passes and processes the capsule file.
> >
> > +
> >
> > +  @param  CapsuleHeaderArray    Virtual pointer to an array of virtual
> > pointers to the capsules
> >
> > +                                being passed into update capsule.
> >
> > +  @param  CapsuleCount          Number of pointers to EFI_CAPSULE_HEADER
> > in CaspuleHeaderArray.
> >
> > +
> >
> > +  @retval EFI_SUCCESS           Valid capsule was passed.
> >
> > +  @retval others                Some error occurs when executing this routine.
> >
> > +
> >
> > +**/
> >
> > +EFI_STATUS
> >
> > +EFIAPI
> >
> > +UpdateCapsule (
> >
> > +  IN EFI_CAPSULE_HEADER  **CapsuleHeaderArray,
> >
> > +  IN UINTN               CapsuleCount
> >
> > +  )
> >
> > +{
> >
> > +  UINTN               ArrayNumber;
> >
> > +  EFI_STATUS          Status;
> >
> > +  EFI_CAPSULE_HEADER  *CapsuleHeader;
> >
> > +
> >
> > +  //
> >
> > +  // Capsule Count can't be less than one.
> >
> > +  //
> >
> > +  if (CapsuleCount < 1) {
> >
> > +    return EFI_INVALID_PARAMETER;
> >
> > +  }
> >
> > +
> >
> > +  CapsuleHeader = NULL;
> >
> > +
> >
> > +  for (ArrayNumber = 0; ArrayNumber < CapsuleCount; ArrayNumber++) {
> >
> > +    //
> >
> > +    // A capsule which has the CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE
> > flag must have
> >
> > +    // CAPSULE_FLAGS_PERSIST_ACROSS_RESET set in its header as well.
> >
> > +    //
> >
> > +    CapsuleHeader = CapsuleHeaderArray[ArrayNumber];
> >
> > +    if ((CapsuleHeader->Flags & (CAPSULE_FLAGS_PERSIST_ACROSS_RESET |
> > CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE)) ==
> > CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) {
> >
> > +      return EFI_INVALID_PARAMETER;
> >
> > +    }
> >
> > +
> >
> > +    //
> >
> > +    // A capsule which has the CAPSULE_FLAGS_INITIATE_RESET flag must
> > have
> >
> > +    // CAPSULE_FLAGS_PERSIST_ACROSS_RESET set in its header as well.
> >
> > +    //
> >
> > +    if ((CapsuleHeader->Flags & (CAPSULE_FLAGS_PERSIST_ACROSS_RESET |
> > CAPSULE_FLAGS_INITIATE_RESET)) == CAPSULE_FLAGS_INITIATE_RESET) {
> >
> > +      return EFI_INVALID_PARAMETER;
> >
> > +    }
> >
> > +
> >
> > +    // FIXME: The CoD Image CANNOT BE RELOADED as Memory capsule.
> >
> > +    //
> >
> > +    // Check FMP capsule flag
> >
> > +    //
> >
> > +    if (  CompareGuid (&CapsuleHeader->CapsuleGuid,
> &gEfiFmpCapsuleGuid)
> >
> > +       && ((CapsuleHeader->Flags &
> > CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) != 0))
> >
> > +    {
> >
> > +      return EFI_INVALID_PARAMETER;
> >
> > +    }
> >
> > +
> >
> > +    //
> >
> > +    // Check Capsule image without populate flag by firmware support
> capsule
> > function
> >
> > +    //
> >
> > +    if ((CapsuleHeader->Flags &
> CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE)
> > == 0) {
> >
> > +      Status = SupportCapsuleImage (CapsuleHeader);
> >
> > +      if (EFI_ERROR (Status)) {
> >
> > +        return Status;
> >
> > +      }
> >
> > +    }
> >
> > +  }
> >
> > +
> >
> > +  //
> >
> > +  // Walk through all capsules, record whether there is a capsule needs reset
> >
> > +  // or initiate reset. And then process capsules which has no reset flag
> > directly.
> >
> > +  //
> >
> > +  for (ArrayNumber = 0; ArrayNumber < CapsuleCount; ArrayNumber++) {
> >
> > +    CapsuleHeader = CapsuleHeaderArray[ArrayNumber];
> >
> > +    //
> >
> > +    // Here should be in the boot-time for non-reset capsule image
> >
> > +    // Platform specific update for the non-reset capsule image.
> >
> > +    //
> >
> > +
> >
> > +    // FIXME: The CoD Image CANNOT BE RELOADED as Memory capsule.
> >
> > +    if (((CapsuleHeader->Flags & CAPSULE_FLAGS_PERSIST_ACROSS_RESET)
> ==
> > 0) || TRUE) {
> >
> > +      Status = ProcessCapsuleImage (CapsuleHeader);
> >
> > +      if (EFI_ERROR (Status)) {
> >
> > +        return Status;
> >
> > +      }
> >
> > +    }
> >
> > +  }
> >
> > +
> >
> > +  return EFI_SUCCESS;
> >
> > +}
> >
> > +
> >
> > +/**
> >
> > +  Detect Capsule file from ESP partition and update capsule.
> >
> > +
> >
> > +  @retval EFI_SUCCESS               Opertion is successful.
> >
> > +  @retval EFI_OUT_OF_RESOURCES      No enough buffer to allocate.
> >
> > +  @retval EFI_ERROR                 Internal error when update Capsule.
> >
> > +
> >
> > +**/
> >
> > +EFI_STATUS
> >
> > +EFIAPI
> >
> > +CapsuleUpdateViaFileHook (
> >
> > +  VOID
> >
> > +  )
> >
> > +{
> >
> > +  EFI_STATUS          Status;
> >
> > +  UINT8               *CapsuleBuffer;
> >
> > +  UINTN               CapsuleSize;
> >
> > +  EFI_CAPSULE_HEADER  *CapsuleHeader;
> >
> > +  UINTN               CapsuleNum;
> >
> > +
> >
> > +  CapsuleBuffer = NULL;
> >
> > +  CapsuleSize   = 0;
> >
> > +
> >
> > +  DEBUG ((DEBUG_INFO, "CapsuleUpdateViaFileHook() Entry Point...\n"));
> >
> > +
> >
> > +  Status = CapsulePartitionInfo ();
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    DEBUG ((DEBUG_ERROR, "CapsulePartitionInfo failed: %r\n", Status));
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  Status = ReadCapsuleInfo (CAP_FILE_NAME, (VOID **)&CapsuleBuffer,
> > &CapsuleSize);
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    DEBUG ((DEBUG_ERROR, "Read Capsule file failed. Status: %r\n",
> Status));
> >
> > +    if (CapsuleBuffer != NULL) {
> >
> > +      FreePool (CapsuleBuffer);
> >
> > +    }
> >
> > +
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  CapsuleHeader = (EFI_CAPSULE_HEADER *)CapsuleBuffer;
> >
> > +  CapsuleNum    = 1;
> >
> > +
> >
> > +  Status = UpdateCapsule (&CapsuleHeader, CapsuleNum);
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    DEBUG ((DEBUG_ERROR, "Failed to update capsule. Status: %r\n",
> Status));
> >
> > +  }
> >
> > +
> >
> > +  if (CapsuleBuffer != NULL) {
> >
> > +    FreePool (CapsuleBuffer);
> >
> > +  }
> >
> > +
> >
> > +  DEBUG ((DEBUG_INFO, "Capsule update via file completed, reset
> > system...\n"));
> >
> > +
> >
> > +  gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
> >
> > +
> >
> > +  return EFI_SUCCESS;
> >
> > +}
> >
> > +
> >
> > +/**
> >
> > +  Get capsule partition device path by partition name.
> >
> > +
> >
> > +  @param[in]  BootDevicePath      Pointer to the Device Path Protocol from
> > variable.
> >
> > +  @param[in]  PartitionName       The given partition name.
> >
> > +  @param[out] PartitionDevicePath Pointer to the Device Path Protocol of
> > capsule partition.
> >
> > +
> >
> > +  @retval EFI_SUCCESS             Operation completed successfully.
> >
> > +  @retval others                  Some error occurs when executing this routine.
> >
> > +
> >
> > +**/
> >
> > +EFI_STATUS
> >
> > +EFIAPI
> >
> > +GetDevicePathByBoot (
> >
> > +  IN  EFI_DEVICE_PATH_PROTOCOL  *BootDevicePath,
> >
> > +  OUT EFI_DEVICE_PATH_PROTOCOL  **PartitionDevicePath
> >
> > +  )
> >
> > +{
> >
> > +  EFI_STATUS                Status;
> >
> > +  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
> >
> > +  EFI_BLOCK_IO_PROTOCOL     *BlockIo;
> >
> > +  EFI_DEVICE_PATH_PROTOCOL  *NextNode;
> >
> > +  UINTN                     NumHandles;
> >
> > +  UINTN                     LoopIndex;
> >
> > +  EFI_HANDLE                *AllHandles;
> >
> > +  EFI_HANDLE                Handle;
> >
> > +
> >
> > +  //
> >
> > +  // Get all BlockIo handles in system
> >
> > +  //
> >
> > +  Status = gBS->LocateHandleBuffer (
> >
> > +                  ByProtocol,
> >
> > +                  &gEfiBlockIoProtocolGuid,
> >
> > +                  NULL,
> >
> > +                  &NumHandles,
> >
> > +                  &AllHandles
> >
> > +                  );
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    DEBUG ((DEBUG_ERROR, "Couldn't locate BlockIo protocol: %r\n",
> > Status));
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  for (LoopIndex = 0; LoopIndex < NumHandles; LoopIndex++) {
> >
> > +    Status = gBS->OpenProtocol (
> >
> > +                    AllHandles[LoopIndex],
> >
> > +                    &gEfiDevicePathProtocolGuid,
> >
> > +                    (VOID **)&DevicePath,
> >
> > +                    gImageHandle,
> >
> > +                    NULL,
> >
> > +                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
> >
> > +                    );
> >
> > +    if (EFI_ERROR (Status)) {
> >
> > +      DEBUG ((DEBUG_ERROR, "Couldn't locate DevicePath protocol: %r\n",
> > Status));
> >
> > +      return Status;
> >
> > +    }
> >
> > +
> >
> > +    if (!CompareMem (DevicePath, BootDevicePath,
> FLASH_DEVICE_PATH_SIZE
> > (BootDevicePath))) {
> >
> > +      BootDevicePath = DevicePath;
> >
> > +      break;
> >
> > +    }
> >
> > +  }
> >
> > +
> >
> > +  DevicePath = BootDevicePath;
> >
> > +  Status     = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid,
> &DevicePath,
> > &Handle);
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    DEBUG ((DEBUG_ERROR, "Couldn't locate device status: %r\n", Status));
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  Status = gBS->OpenProtocol (
> >
> > +                  Handle,
> >
> > +                  &gEfiBlockIoProtocolGuid,
> >
> > +                  (VOID **)&BlockIo,
> >
> > +                  gImageHandle,
> >
> > +                  NULL,
> >
> > +                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
> >
> > +                  );
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    DEBUG ((DEBUG_ERROR, "Failed to get BlockIo: %r\n", Status));
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  for (LoopIndex = 0; LoopIndex < NumHandles; LoopIndex++) {
> >
> > +    Status = gBS->OpenProtocol (
> >
> > +                    AllHandles[LoopIndex],
> >
> > +                    &gEfiDevicePathProtocolGuid,
> >
> > +                    (VOID **)&DevicePath,
> >
> > +                    gImageHandle,
> >
> > +                    NULL,
> >
> > +                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
> >
> > +                    );
> >
> > +    if (EFI_ERROR (Status)) {
> >
> > +      DEBUG ((DEBUG_ERROR, "Couldn't locate DevicePath protocol: %r\n",
> > Status));
> >
> > +      return Status;
> >
> > +    }
> >
> > +
> >
> > +    if (!CompareMem (DevicePath, BootDevicePath,
> FLASH_DEVICE_PATH_SIZE
> > (BootDevicePath))) {
> >
> > +      NextNode = NextDevicePathNode (DevicePath);
> >
> > +
> >
> > +      while (!IsDevicePathEndType (NextNode)) {
> >
> > +        if ((NextNode->Type == MEDIA_DEVICE_PATH) &&
> >
> > +            (NextNode->SubType == MEDIA_HARDDRIVE_DP))
> >
> > +        {
> >
> > +          break;
> >
> > +        }
> >
> > +
> >
> > +        NextNode = NextDevicePathNode (NextNode);
> >
> > +      }
> >
> > +
> >
> > +      if (IsDevicePathEndType (NextNode)) {
> >
> > +        continue;
> >
> > +      }
> >
> > +
> >
> > +      break;
> >
> > +    }
> >
> > +  }
> >
> > +
> >
> > +  if (LoopIndex >= NumHandles) {
> >
> > +    return EFI_LOAD_ERROR;
> >
> > +  }
> >
> > +
> >
> > +  *PartitionDevicePath = DevicePath;
> >
> > +
> >
> > +  return EFI_SUCCESS;
> >
> > +}
> >
> > +
> >
> > +/**
> >
> > +  Get capsule paritioin information.
> >
> > +
> >
> > +  @param[in]  VOID
> >
> > +
> >
> > +  @retval EFI_SUCCESS             Operation completed successfully.
> >
> > +  @retval others                  Some error occurs when executing this routine.
> >
> > +
> >
> > +**/
> >
> > +EFI_STATUS
> >
> > +EFIAPI
> >
> > +CapsulePathInfo (
> >
> > +  VOID
> >
> > +  )
> >
> > +{
> >
> > +  mBootDevicePath = ConvertTextToDevicePath ((CHAR16 *)PcdGetPtr
> > (PcdNVMeDevicePath));
> >
> > +
> >
> > +  if (mBootDevicePath == NULL) {
> >
> > +    DEBUG ((DEBUG_ERROR, "mBootDevicePath is NULL\n"));
> >
> > +    return EFI_NOT_FOUND;
> >
> > +  }
> >
> > +
> >
> > +  return EFI_SUCCESS;
> >
> > +}
> >
> > +
> >
> > +/**
> >
> > +  Read Capsule file information from FAT partiton.
> >
> > +
> >
> > +  @param[in]  FileName              File name of Capsule binary
> >
> > +  @param[out] Buffer                Return buffer pointer of Capsule binary
> >
> > +  @param[out] BufferSize            Capsule binary size
> >
> > +
> >
> > +  @retval EFI_SUCCESS               Read Capsule information successfully
> >
> > +  @retval EFI_OUT_OF_RESOURCES      No enough buffer to allocate
> >
> > +  @retval EFI_NOT_FOUND             Fail to read Capsule information
> >
> > +  @retval Others                    Internal error when read Capsule information
> >
> > +
> >
> > +**/
> >
> > +EFI_STATUS
> >
> > +EFIAPI
> >
> > +IterateAllCapsulesFromDisk (
> >
> > +  IN CHAR16    *FileBaseName,
> >
> > +  OUT VOID     **Buffer,
> >
> > +  OUT UINTN    *BufferSize,
> >
> > +  OUT BOOLEAN  *NoNextFile
> >
> > +  )
> >
> > +{
> >
> > +  EFI_STATUS                       Status;
> >
> > +  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL  *Fs;
> >
> > +  EFI_FILE                         *Root;
> >
> > +  EFI_FILE                         *DirHandle;
> >
> > +  EFI_FILE                         *FileHandle;
> >
> > +  EFI_FILE_INFO                    *FileInfo;
> >
> > +  UINT8                            *FileBuffer;
> >
> > +  EFI_HANDLE                       Handle;
> >
> > +  EFI_BLOCK_IO_PROTOCOL            *BlockIo;
> >
> > +  EFI_DEVICE_PATH_PROTOCOL         *BootPartitionPath;
> >
> > +  BOOLEAN                          Found = FALSE;
> >
> > +
> >
> > +  FileBuffer = NULL;
> >
> > +
> >
> > +  DEBUG ((DEBUG_INFO, "ReadCapsuleInfo()...\n"));
> >
> > +
> >
> > +  Status = GetDevicePathByBoot (mBootDevicePath, &BootPartitionPath);
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    DEBUG ((DEBUG_ERROR, "GetDevicePathByName failed: %r\n", Status));
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  DEBUG ((DEBUG_INFO, "IGpuDevicePath: %S\n",
> ConvertDevicePathToText
> > (BootPartitionPath, FALSE, FALSE)));
> >
> > +
> >
> > +  Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid,
> > &BootPartitionPath, &Handle);
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    DEBUG ((DEBUG_ERROR, "ReadCapsuleInfo: Locate DevicePath failed:
> > %r\n", Status));
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  //
> >
> > +  // Get Capsule file
> >
> > +  //
> >
> > +  Status = gBS->HandleProtocol (Handle, &gEfiBlockIoProtocolGuid, (VOID
> > **)&BlockIo);
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    DEBUG ((DEBUG_ERROR, "ReadCapsuleInfo: 1Locate DevicePath failed:
> > %r\n", Status));
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  if (BlockIo->Media->RemovableMedia) {
> >
> > +    DEBUG ((DEBUG_ERROR, "ReadCapsuleInfo: 2Locate DevicePath failed:
> > %r\n", Status));
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  Status = gBS->HandleProtocol (Handle,
> &gEfiSimpleFileSystemProtocolGuid,
> > (VOID **)&Fs);
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    DEBUG ((DEBUG_ERROR, "ReadCapsuleInfo: 3Locate DevicePath failed:
> > %r\n", Status));
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  Status = Fs->OpenVolume (Fs, &Root);
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    DEBUG ((DEBUG_ERROR, "ReadCapsuleInfo: 4Locate DevicePath failed:
> > %r\n", Status));
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  Status = Root->Open (Root, &DirHandle, FileBaseName,
> > EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE, 0);
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    DEBUG ((DEBUG_ERROR, "Cannot open %s. Status = %r\n",
> FileBaseName,
> > Status));
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  //
> >
> > +  // Get file count first
> >
> > +  //
> >
> > +  Status = FileHandleFindFirstFile (DirHandle, &FileInfo);
> >
> > +  while (!*NoNextFile && !Found) {
> >
> > +    // . & ..
> >
> > +    Status = FileHandleFindNextFile (DirHandle, FileInfo, NoNextFile);
> >
> > +    if (EFI_ERROR (Status)) {
> >
> > +      return Status;
> >
> > +    }
> >
> > +
> >
> > +    if (FileInfo->Attribute & EFI_FILE_DIRECTORY) {
> >
> > +      continue;
> >
> > +    }
> >
> > +
> >
> > +    Found = TRUE;
> >
> > +  }
> >
> > +
> >
> > +  if (!Found) {
> >
> > +    *NoNextFile = TRUE;
> >
> > +    return EFI_NOT_FOUND;
> >
> > +  }
> >
> > +
> >
> > +  DEBUG ((DEBUG_INFO, "Processing Capsule %s\n", FileInfo->FileName));
> >
> > +  FileBuffer = AllocateZeroPool (FileInfo->FileSize);
> >
> > +  if (FileBuffer == NULL) {
> >
> > +    return EFI_BUFFER_TOO_SMALL;
> >
> > +  }
> >
> > +
> >
> > +  Status = DirHandle->Open (DirHandle, &FileHandle, FileInfo->FileName,
> > EFI_FILE_MODE_READ, 0);
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    DEBUG ((DEBUG_ERROR, "ReadCapsuleInfo Cannot open file %s: %r\n",
> > FileInfo->FileName, Status));
> >
> > +    FreePool (FileBuffer);
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  Status = FileHandleRead (FileHandle, &FileInfo->FileSize, FileBuffer);
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    DEBUG ((DEBUG_ERROR, "ReadCapsuleInfo: 7Locate DevicePath failed:
> > %r\n", Status));
> >
> > +    FileHandleClose (FileHandle);
> >
> > +    FreePool (FileBuffer);
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  if (!*NoNextFile) {
> >
> > +    Status = FileHandleClose (DirHandle);
> >
> > +  }
> >
> > +
> >
> > +  Status = FileHandleClose (FileHandle);
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    DEBUG ((DEBUG_ERROR, "ReadCapsuleInfo: 8Locate DevicePath failed:
> > %r\n", Status));
> >
> > +    FreePool (FileBuffer);
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  *Buffer     = FileBuffer;
> >
> > +  *BufferSize = FileInfo->FileSize;
> >
> > +
> >
> > +  DEBUG ((DEBUG_INFO, "Capsule size: 0x%x\n", *BufferSize));
> >
> > +
> >
> > +  return EFI_SUCCESS;
> >
> > +}
> >
> > +
> >
> > +/**
> >
> > +  Read Capsule file information from FAT partiton.
> >
> > +
> >
> > +  @param[in]  FileBaseName              File name of Capsule binary
> >
> > +
> >
> > +  @retval EFI_SUCCESS               Delete first capsule successfully
> >
> > +  @retval EFI_NOT_FOUND             Fail to found Capsule information
> >
> > +
> >
> > +**/
> >
> > +EFI_STATUS
> >
> > +EFIAPI
> >
> > +DeleteFirstCapsule (
> >
> > +  CHAR16  *FileBaseName
> >
> > +  )
> >
> > +{
> >
> > +  EFI_DEVICE_PATH_PROTOCOL         *BootPartitionPath;
> >
> > +  EFI_HANDLE                       Handle;
> >
> > +  EFI_STATUS                       Status;
> >
> > +  EFI_BLOCK_IO_PROTOCOL            *BlockIo;
> >
> > +  EFI_FILE_PROTOCOL                *Root;
> >
> > +  EFI_FILE_HANDLE                  DirHandle;
> >
> > +  BOOLEAN                          NoNextFile = FALSE;
> >
> > +  EFI_FILE_INFO                    *FileInfo;
> >
> > +  BOOLEAN                          Found = FALSE;
> >
> > +  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL  *Fs;
> >
> > +  EFI_FILE_HANDLE                  FileHandle;
> >
> > +
> >
> > +  Status = GetDevicePathByBoot (mBootDevicePath, &BootPartitionPath);
> >
> > +
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    DEBUG ((DEBUG_ERROR, "GetDevicePathByName failed: %r\n", Status));
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  DEBUG ((DEBUG_INFO, "IGpuDevicePath: %S\n",
> ConvertDevicePathToText
> > (BootPartitionPath, FALSE, FALSE)));
> >
> > +
> >
> > +  Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid,
> > &BootPartitionPath, &Handle);
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    DEBUG ((DEBUG_ERROR, "ReadCapsuleInfo: Locate DevicePath failed:
> > %r\n", Status));
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  //
> >
> > +  // Get Capsule file
> >
> > +  //
> >
> > +  Status = gBS->HandleProtocol (Handle, &gEfiBlockIoProtocolGuid, (VOID
> > **)&BlockIo);
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    DEBUG ((DEBUG_ERROR, "ReadCapsuleInfo: 1Locate DevicePath failed:
> > %r\n", Status));
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  if (BlockIo->Media->RemovableMedia) {
> >
> > +    DEBUG ((DEBUG_ERROR, "ReadCapsuleInfo: 2Locate DevicePath failed:
> > %r\n", Status));
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  Status = gBS->HandleProtocol (Handle,
> &gEfiSimpleFileSystemProtocolGuid,
> > (VOID **)&Fs);
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    DEBUG ((DEBUG_ERROR, "ReadCapsuleInfo: 3Locate DevicePath failed:
> > %r\n", Status));
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  Status = Fs->OpenVolume (Fs, &Root);
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    DEBUG ((DEBUG_ERROR, "ReadCapsuleInfo: 4Locate DevicePath failed:
> > %r\n", Status));
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  Status = Root->Open (Root, &DirHandle, FileBaseName,
> > EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE, 0);
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    DEBUG ((DEBUG_ERROR, "Cannot open %s. Status = %r\n",
> FileBaseName,
> > Status));
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  Status = FileHandleFindFirstFile (DirHandle, &FileInfo);
> >
> > +  while (!NoNextFile && !Found) {
> >
> > +    // . & ..
> >
> > +    FileHandleFindNextFile (DirHandle, FileInfo, &NoNextFile);
> >
> > +    if (FileInfo->Attribute & EFI_FILE_DIRECTORY) {
> >
> > +      continue;
> >
> > +    }
> >
> > +
> >
> > +    Found = TRUE;
> >
> > +  }
> >
> > +
> >
> > +  if (!Found) {
> >
> > +    return EFI_NOT_FOUND;
> >
> > +  }
> >
> > +
> >
> > +  DEBUG ((DEBUG_INFO, "Deleting Capsule %s\n", FileInfo->FileName));
> >
> > +  Status = DirHandle->Open (DirHandle, &FileHandle, FileInfo->FileName,
> > EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE, 0);
> >
> > +  if (!EFI_ERROR (Status)) {
> >
> > +    Status = FileHandle->Delete (FileHandle);
> >
> > +    if (EFI_ERROR (Status)) {
> >
> > +      DEBUG ((DEBUG_INFO, "Cannot delete Capsule %s:%r\n", FileInfo-
> > >FileName, Status));
> >
> > +    }
> >
> > +
> >
> > +    DirHandle->Close (DirHandle);
> >
> > +    Root->Close (Root);
> >
> > +    return EFI_SUCCESS;
> >
> > +  }
> >
> > +
> >
> > +  return EFI_NOT_FOUND;
> >
> > +}
> >
> > +
> >
> > +/**
> >
> > +  Detect Capsule file from ESP partition and update capsule.
> >
> > +
> >
> > +  @retval EFI_SUCCESS               Opertion is successful.
> >
> > +  @retval EFI_OUT_OF_RESOURCES      No enough buffer to allocate.
> >
> > +  @retval EFI_ERROR                 Internal error when update Capsule.
> >
> > +
> >
> > +**/
> >
> > +EFI_STATUS
> >
> > +EFIAPI
> >
> > +CapsuleUpdateViaFileLib (
> >
> > +  VOID
> >
> > +  )
> >
> > +{
> >
> > +  EFI_STATUS          Status;
> >
> > +  UINT8               *CapsuleBuffer;
> >
> > +  UINTN               CapsuleSize;
> >
> > +  EFI_CAPSULE_HEADER  *CapsuleHeader;
> >
> > +  UINTN               CapsuleNum;
> >
> > +  UINTN               CurrentCapsuleFileNo = 0;
> >
> > +  BOOLEAN             NoNextFile           = FALSE;
> >
> > +
> >
> > +  CapsuleBuffer = NULL;
> >
> > +  CapsuleSize   = 0;
> >
> > +
> >
> > +  DEBUG ((DEBUG_INFO, "CapsuleUpdateViaFileHook() Entry Point...\n"));
> >
> > +
> >
> > +  Status = CapsulePathInfo ();
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    DEBUG ((DEBUG_ERROR, "CapsulePathInfo failed: %r\n", Status));
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  while (!NoNextFile) {
> >
> > +    Status = IterateAllCapsulesFromDisk (EFI_CAPSULE_FILE_DIRECTORY,
> (VOID
> > **)&CapsuleBuffer, &CapsuleSize, &NoNextFile);
> >
> > +    if (EFI_ERROR (Status)) {
> >
> > +      DEBUG ((DEBUG_ERROR, "Failed to update capsule:%r\n", Status));
> >
> > +      break;
> >
> > +    }
> >
> > +
> >
> > +    CapsuleHeader = (EFI_CAPSULE_HEADER *)CapsuleBuffer;
> >
> > +    CapsuleNum    = 1;
> >
> > +    Status        = UpdateCapsule (&CapsuleHeader, CapsuleNum);
> >
> > +    RecordCapsuleStatusVariable (CapsuleHeader, Status);
> >
> > +    if (EFI_ERROR (Status)) {
> >
> > +      DEBUG ((DEBUG_ERROR, "Failed to update capsule.\n"));
> >
> > +      break;
> >
> > +    }
> >
> > +
> >
> > +    Status = DeleteFirstCapsule (EFI_CAPSULE_FILE_DIRECTORY);
> >
> > +    if (EFI_ERROR (Status)) {
> >
> > +      DEBUG ((DEBUG_ERROR, "Cannot delete Capsule.\n"));
> >
> > +      break;
> >
> > +    }
> >
> > +  }
> >
> > +
> >
> > +  if (CapsuleBuffer != NULL) {
> >
> > +    FreePool (CapsuleBuffer);
> >
> > +  }
> >
> > +
> >
> > +  if (!CurrentCapsuleFileNo && (Status == EFI_NOT_FOUND)) {
> >
> > +    Status = EFI_SUCCESS;
> >
> > +  }
> >
> > +
> >
> > +  DEBUG ((DEBUG_INFO, "Capsule update via file completed, Status=%r\n",
> > Status));
> >
> > +  // RecordFmpCapsuleStatus();
> >
> > +  gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
> >
> > +
> >
> > +  // Unreachable.
> >
> > +  return EFI_SUCCESS;
> >
> > +}
> >
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/ChachaniBoardPkg/Library/Capsule/Capsul
> > eHookLib/CapsuleHookLib.inf
> >
> b/Platform/AMD/VanGoghBoard/ChachaniBoardPkg/Library/Capsule/Capsul
> > eHookLib/CapsuleHookLib.inf
> >
> > new file mode 100644
> >
> > index 0000000000..c3e910007a
> >
> > --- /dev/null
> >
> > +++
> >
> b/Platform/AMD/VanGoghBoard/ChachaniBoardPkg/Library/Capsule/Capsul
> > eHookLib/CapsuleHookLib.inf
> >
> > @@ -0,0 +1,56 @@
> >
> > +## @file
> >
> > +# Capsule Hook Lib Module
> >
> > +#
> >
> > +# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
> >
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> >
> > +#
> >
> > +##
> >
> > +
> >
> > +[Defines]
> >
> > +  INF_VERSION                    = 0x00010005
> >
> > +  BASE_NAME                      = CapsuleHookLib
> >
> > +  FILE_GUID                      = 22BC4D9A-C78A-4038-8071-865765C4C019
> >
> > +  MODULE_TYPE                    = DXE_DRIVER
> >
> > +  VERSION_STRING                 = 1.0
> >
> > +  LIBRARY_CLASS                  = CapsuleHookLib
> >
> > +
> >
> > +#
> >
> > +# The following information is for reference only and not required by the
> build
> > tools.
> >
> > +#
> >
> > +#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC
> >
> > +#
> >
> > +
> >
> > +[Sources]
> >
> > +  CapsuleHookLib.c
> >
> > +
> >
> > +[Packages]
> >
> > +  MdePkg/MdePkg.dec
> >
> > +  MdeModulePkg/MdeModulePkg.dec
> >
> > +  VanGoghCommonPkg/AmdCommonPkg.dec
> >
> > +  ChachaniBoardPkg/Project.dec
> >
> > +
> >
> > +[LibraryClasses]
> >
> > +  BaseLib
> >
> > +  MemoryAllocationLib
> >
> > +  UefiBootServicesTableLib
> >
> > +  UefiRuntimeServicesTableLib
> >
> > +  BaseMemoryLib
> >
> > +  DebugLib
> >
> > +  UefiLib
> >
> > +  FileHandleLib
> >
> > +  DxeServicesLib
> >
> > +  CapsuleLib
> >
> > +
> >
> > +[Protocols]
> >
> > +  gEfiBlockIoProtocolGuid
> >
> > +  gEfiSimpleFileSystemProtocolGuid
> >
> > +
> >
> > +[Pcd]
> >
> > +  gAmdCommonPkgTokenSpaceGuid.PcdOtaCapsuleName
> >
> > +  gAmdCommonPkgTokenSpaceGuid.PcdOtaCapsulePartitionName
> >
> > +  gPlatformPkgTokenSpaceGuid.PcdNVMeDevicePath
> >
> > +
> >
> > +[Guids]
> >
> > +  gEfiFmpCapsuleGuid
> >
> > +  gEfiGlobalVariableGuid
> >
> > +  gOtaCapsuleUpdateGuid
> >
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/ChachaniBoardPkg/Library/Capsule/Platfor
> > mBootManagerLib/PlatformBootManager.c
> >
> b/Platform/AMD/VanGoghBoard/ChachaniBoardPkg/Library/Capsule/Platfor
> > mBootManagerLib/PlatformBootManager.c
> >
> > new file mode 100644
> >
> > index 0000000000..a647e92054
> >
> > --- /dev/null
> >
> > +++
> >
> b/Platform/AMD/VanGoghBoard/ChachaniBoardPkg/Library/Capsule/Platfor
> > mBootManagerLib/PlatformBootManager.c
> >
> > @@ -0,0 +1,803 @@
> >
> > +/** @file
> >
> > +  Implements PlatformBootManager.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
> >
> > +  This file include all platform action which can be customized
> >
> > +  by IBV/OEM.
> >
> > +
> >
> > +Copyright (c) 2015 - 2021, Intel Corporation. All rights reserved.<BR>
> >
> > +SPDX-License-Identifier: BSD-2-Clause-Patent
> >
> > +
> >
> > +**/
> >
> > +//
> >
> > +// PCI Vendor ID and Device ID
> >
> > +//
> >
> > +#define VENDOR_ID   0x1002
> >
> > +#define DEVICE_ID   0x163F
> >
> > +#define DEVICE_ID2  0x1435
> >
> > +
> >
> > +#include "PlatformBootManager.h"
> >
> > +#include "PlatformConsole.h"
> >
> > +#include <Protocol/PlatformBootManagerOverride.h>
> >
> > +#include <Guid/BootManagerMenu.h>
> >
> > +#include <Library/HobLib.h>
> >
> > +#include <Library/DxeServicesTableLib.h>
> >
> > +#include <Library/DebugLib.h>
> >
> > +#include <Library/CapsuleHookLib.h>
> >
> > +#include <Library/CapsuleLib.h>
> >
> > +
> >
> > +//
> >
> > +// Predefined platform root bridge
> >
> > +//
> >
> > +PLATFORM_ROOT_BRIDGE_DEVICE_PATH  gPlatformRootBridge0 = {
> >
> > +  gPciRootBridge,
> >
> > +  gEndEntire
> >
> > +};
> >
> > +
> >
> > +EFI_DEVICE_PATH_PROTOCOL  *gPlatformRootBridges[] = {
> >
> > +  (EFI_DEVICE_PATH_PROTOCOL *)&gPlatformRootBridge0,
> >
> > +  NULL
> >
> > +};
> >
> > +
> >
> > +extern EFI_GUID                                            gEfiEventReadyToBootGuid;
> >
> >
> +UNIVERSAL_PAYLOAD_PLATFORM_BOOT_MANAGER_OVERRIDE_PROTOCO
> > L  *mUniversalPayloadPlatformBootManagerOverrideInstance = NULL;
> >
> > +
> >
> > +EFI_STATUS
> >
> > +GetGopDevicePath (
> >
> > +  IN  EFI_DEVICE_PATH_PROTOCOL  *PciDevicePath,
> >
> > +  OUT EFI_DEVICE_PATH_PROTOCOL  **GopDevicePath
> >
> > +  );
> >
> > +
> >
> > +/**
> >
> > +  Signal EndOfDxe event and install SMM Ready to lock protocol.
> >
> > +
> >
> > +**/
> >
> > +VOID
> >
> > +InstallReadyToLock (
> >
> > +  VOID
> >
> > +  )
> >
> > +{
> >
> > +  EFI_STATUS                Status;
> >
> > +  EFI_HANDLE                Handle;
> >
> > +  EFI_SMM_ACCESS2_PROTOCOL  *SmmAccess;
> >
> > +
> >
> > +  DEBUG ((DEBUG_INFO, "InstallReadyToLock  entering......\n"));
> >
> > +  //
> >
> > +  // Inform the SMM infrastructure that we're entering BDS and may run
> 3rd
> > party code hereafter
> >
> > +  // Since PI1.2.1, we need signal EndOfDxe as ExitPmAuth
> >
> > +  //
> >
> > +  EfiEventGroupSignal (&gEfiEndOfDxeEventGroupGuid);
> >
> > +  DEBUG ((DEBUG_INFO, "All EndOfDxe callbacks have returned
> > successfully\n"));
> >
> > +
> >
> > +  //
> >
> > +  // Install DxeSmmReadyToLock protocol in order to lock SMM
> >
> > +  //
> >
> > +  Status = gBS->LocateProtocol (&gEfiSmmAccess2ProtocolGuid, NULL,
> (VOID
> > **)&SmmAccess);
> >
> > +  if (!EFI_ERROR (Status)) {
> >
> > +    Handle = NULL;
> >
> > +    Status = gBS->InstallProtocolInterface (
> >
> > +                    &Handle,
> >
> > +                    &gEfiDxeSmmReadyToLockProtocolGuid,
> >
> > +                    EFI_NATIVE_INTERFACE,
> >
> > +                    NULL
> >
> > +                    );
> >
> > +    ASSERT_EFI_ERROR (Status);
> >
> > +  }
> >
> > +
> >
> > +  DEBUG ((DEBUG_INFO, "InstallReadyToLock  end\n"));
> >
> > +  return;
> >
> > +}
> >
> > +
> >
> > +/**
> >
> > +  Return the index of the load option in the load option array.
> >
> > +
> >
> > +  The function consider two load options are equal when the
> >
> > +  OptionType, Attributes, Description, FilePath and OptionalData are equal.
> >
> > +
> >
> > +  @param Key    Pointer to the load option to be found.
> >
> > +  @param Array  Pointer to the array of load options to be found.
> >
> > +  @param Count  Number of entries in the Array.
> >
> > +
> >
> > +  @retval -1          Key wasn't found in the Array.
> >
> > +  @retval 0 ~ Count-1 The index of the Key in the Array.
> >
> > +**/
> >
> > +INTN
> >
> > +PlatformFindLoadOption (
> >
> > +  IN CONST EFI_BOOT_MANAGER_LOAD_OPTION  *Key,
> >
> > +  IN CONST EFI_BOOT_MANAGER_LOAD_OPTION  *Array,
> >
> > +  IN UINTN                               Count
> >
> > +  )
> >
> > +{
> >
> > +  UINTN  Index;
> >
> > +
> >
> > +  for (Index = 0; Index < Count; Index++) {
> >
> > +    if ((Key->OptionType == Array[Index].OptionType) &&
> >
> > +        (Key->Attributes == Array[Index].Attributes) &&
> >
> > +        (StrCmp (Key->Description, Array[Index].Description) == 0) &&
> >
> > +        (CompareMem (Key->FilePath, Array[Index].FilePath,
> GetDevicePathSize
> > (Key->FilePath)) == 0) &&
> >
> > +        (Key->OptionalDataSize == Array[Index].OptionalDataSize) &&
> >
> > +        (CompareMem (Key->OptionalData, Array[Index].OptionalData, Key-
> > >OptionalDataSize) == 0))
> >
> > +    {
> >
> > +      return (INTN)Index;
> >
> > +    }
> >
> > +  }
> >
> > +
> >
> > +  return -1;
> >
> > +}
> >
> > +
> >
> > +/**
> >
> > +  Register a boot option using a file GUID in the FV.
> >
> > +
> >
> > +  @param FileGuid     The file GUID name in FV.
> >
> > +  @param Description  The boot option description.
> >
> > +  @param Attributes   The attributes used for the boot option loading.
> >
> > +**/
> >
> > +VOID
> >
> > +PlatformRegisterFvBootOption (
> >
> > +  EFI_GUID  *FileGuid,
> >
> > +  CHAR16    *Description,
> >
> > +  UINT32    Attributes
> >
> > +  )
> >
> > +{
> >
> > +  EFI_STATUS                         Status;
> >
> > +  UINTN                              OptionIndex;
> >
> > +  EFI_BOOT_MANAGER_LOAD_OPTION       NewOption;
> >
> > +  EFI_BOOT_MANAGER_LOAD_OPTION       *BootOptions;
> >
> > +  UINTN                              BootOptionCount;
> >
> > +  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH  FileNode;
> >
> > +  EFI_LOADED_IMAGE_PROTOCOL          *LoadedImage;
> >
> > +  EFI_DEVICE_PATH_PROTOCOL           *DevicePath;
> >
> > +
> >
> > +  Status = gBS->HandleProtocol (gImageHandle,
> > &gEfiLoadedImageProtocolGuid, (VOID **)&LoadedImage);
> >
> > +  ASSERT_EFI_ERROR (Status);
> >
> > +
> >
> > +  EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid);
> >
> > +  DevicePath = AppendDevicePathNode (
> >
> > +                 DevicePathFromHandle (LoadedImage->DeviceHandle),
> >
> > +                 (EFI_DEVICE_PATH_PROTOCOL *)&FileNode
> >
> > +                 );
> >
> > +
> >
> > +  Status = EfiBootManagerInitializeLoadOption (
> >
> > +             &NewOption,
> >
> > +             LoadOptionNumberUnassigned,
> >
> > +             LoadOptionTypeBoot,
> >
> > +             Attributes,
> >
> > +             Description,
> >
> > +             DevicePath,
> >
> > +             NULL,
> >
> > +             0
> >
> > +             );
> >
> > +  if (!EFI_ERROR (Status)) {
> >
> > +    BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount,
> > LoadOptionTypeBoot);
> >
> > +
> >
> > +    OptionIndex = PlatformFindLoadOption (&NewOption, BootOptions,
> > BootOptionCount);
> >
> > +
> >
> > +    if (OptionIndex == -1) {
> >
> > +      Status = EfiBootManagerAddLoadOptionVariable (&NewOption,
> (UINTN)-
> > 1);
> >
> > +      ASSERT_EFI_ERROR (Status);
> >
> > +    }
> >
> > +
> >
> > +    EfiBootManagerFreeLoadOption (&NewOption);
> >
> > +    EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);
> >
> > +  }
> >
> > +}
> >
> > +
> >
> > +/**
> >
> > +  Get device path of one IGPU and one DGPU.
> >
> > +
> >
> > +  @param IGpuDevicePath   Return the IGPU devide path, if no, return
> NULL.
> >
> > +  @param DGpuDevicePath   Return the DGPU devide path, if no, return
> > NULL.
> >
> > +
> >
> > +  @retval EFI_SUCCSS      Get all platform active video device path.
> >
> > +  @retval EFI_STATUS      Return the status of gBS->LocateDevicePath (),
> >
> > +                          gBS->ConnectController (),
> >
> > +                          and gBS->LocateHandleBuffer ().
> >
> > +**/
> >
> > +EFI_STATUS
> >
> > +GetVgaDevicePath (
> >
> > +  IN OUT EFI_DEVICE_PATH_PROTOCOL  **IGpuDevicePath,
> >
> > +  IN OUT EFI_DEVICE_PATH_PROTOCOL  **DGpuDevicePath
> >
> > +  )
> >
> > +{
> >
> > +  EFI_STATUS                Status;
> >
> > +  EFI_HANDLE                RootHandle;
> >
> > +  UINTN                     HandleCount;
> >
> > +  EFI_HANDLE                *HandleBuffer;
> >
> > +  UINTN                     Index;
> >
> > +  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
> >
> > +  EFI_PCI_IO_PROTOCOL       *PciIo;
> >
> > +  PCI_TYPE00                Pci;
> >
> > +
> >
> > +  DEBUG ((DEBUG_INFO, "GetVgaDevicePath enter\n"));
> >
> > +
> >
> > +  HandleCount     = 0;
> >
> > +  DevicePath      = NULL;
> >
> > +  HandleBuffer    = NULL;
> >
> > +  *IGpuDevicePath = NULL;
> >
> > +  *DGpuDevicePath = NULL;
> >
> > +
> >
> > +  DEBUG ((DEBUG_INFO, "VENDOR_ID = 0x%x\n", VENDOR_ID));
> >
> > +  DEBUG ((DEBUG_INFO, "DEVICE_ID = 0x%x\n", DEVICE_ID));
> >
> > +
> >
> > +  //
> >
> > +  // Make all the PCI_IO protocols on PCI Seg 0 show up
> >
> > +  //
> >
> > +  EfiBootManagerConnectDevicePath (gPlatformRootBridges[0], NULL);
> >
> > +
> >
> > +  Status = gBS->LocateDevicePath (
> >
> > +                  &gEfiDevicePathProtocolGuid,
> >
> > +                  &gPlatformRootBridges[0],
> >
> > +                  &RootHandle
> >
> > +                  );
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  Status = gBS->ConnectController (
> >
> > +                  RootHandle,
> >
> > +                  NULL,
> >
> > +                  NULL,
> >
> > +                  FALSE
> >
> > +                  );
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  //
> >
> > +  // Start to check all the pci io to find all possible VGA device
> >
> > +  //
> >
> > +  HandleCount  = 0;
> >
> > +  HandleBuffer = NULL;
> >
> > +  Status       = gBS->LocateHandleBuffer (
> >
> > +                        ByProtocol,
> >
> > +                        &gEfiPciIoProtocolGuid,
> >
> > +                        NULL,
> >
> > +                        &HandleCount,
> >
> > +                        &HandleBuffer
> >
> > +                        );
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  for (Index = 0; Index < HandleCount; Index++) {
> >
> > +    Status = gBS->HandleProtocol (
> >
> > +                    HandleBuffer[Index],
> >
> > +                    &gEfiPciIoProtocolGuid,
> >
> > +                    (VOID **)&PciIo
> >
> > +                    );
> >
> > +    if (!EFI_ERROR (Status)) {
> >
> > +      //
> >
> > +      // Check for all VGA device
> >
> > +      //
> >
> > +      Status = PciIo->Pci.Read (
> >
> > +                            PciIo,
> >
> > +                            EfiPciIoWidthUint32,
> >
> > +                            0,
> >
> > +                            sizeof (Pci) / sizeof (UINT32),
> >
> > +                            &Pci
> >
> > +                            );
> >
> > +      if (EFI_ERROR (Status)) {
> >
> > +        continue;
> >
> > +      }
> >
> > +
> >
> > +      //
> >
> > +      // Here we decide which VGA device to enable in PCI bus
> >
> > +      //
> >
> > +      // The first plugin PCI VGA card device will be present as PCI VGA
> >
> > +      // The onchip AGP or AGP card will be present as AGP VGA
> >
> > +      //
> >
> > +      if (!IS_PCI_DISPLAY (&Pci)) {
> >
> > +        // if (!IS_PCI_VGA (&Pci)) {
> >
> > +        continue;
> >
> > +      }
> >
> > +
> >
> > +      //
> >
> > +      // Set the device as the possible console out device,
> >
> > +      //
> >
> > +      // Below code will make every VGA device to be one
> >
> > +      // of the possibe console out device
> >
> > +      //
> >
> > +      gBS->HandleProtocol (
> >
> > +             HandleBuffer[Index],
> >
> > +             &gEfiDevicePathProtocolGuid,
> >
> > +             (VOID **)&DevicePath
> >
> > +             );
> >
> > +      DEBUG ((DEBUG_INFO, "DevicePath: %S\n", ConvertDevicePathToText
> > (DevicePath, FALSE, FALSE)));
> >
> > +
> >
> > +      if ((Pci.Hdr.VendorId == VENDOR_ID) && ((Pci.Hdr.DeviceId ==
> DEVICE_ID)
> > || (Pci.Hdr.DeviceId == DEVICE_ID2))) {
> >
> > +        // IGPU
> >
> > +        *IGpuDevicePath = DevicePath;
> >
> > +      } else {
> >
> > +        // DGPU
> >
> > +        *DGpuDevicePath = DevicePath;
> >
> > +      }
> >
> > +
> >
> > +      if ((*IGpuDevicePath != NULL) && (*DGpuDevicePath != NULL)) {
> >
> > +        DEBUG ((DEBUG_INFO, "IGpuDevicePath and DGpuDevicePath are not
> > NULL\n"));
> >
> > +        break;
> >
> > +      }
> >
> > +    }
> >
> > +  }
> >
> > +
> >
> > +  DEBUG ((DEBUG_INFO, "IGpuDevicePath: %S\n",
> ConvertDevicePathToText
> > (*IGpuDevicePath, FALSE, FALSE)));
> >
> > +  DEBUG ((DEBUG_INFO, "DGpuDevicePath: %S\n",
> ConvertDevicePathToText
> > (*DGpuDevicePath, FALSE, FALSE)));
> >
> > +  FreePool (HandleBuffer);
> >
> > +
> >
> > +  return EFI_SUCCESS;
> >
> > +}
> >
> > +
> >
> > +/**
> >
> > +
> >
> > +  Find the platform active vga, and base on the policy to enable the vga as
> >
> > +  the console out device. The policy is active dGPU, if no dGPU active iGPU.
> >
> > +
> >
> > +  None.
> >
> > +
> >
> > +  @param EFI_UNSUPPORTED         There is no active vga device
> >
> > +
> >
> > +  @retval EFI_STATUS             Return the status of BdsLibGetVariableAndSize
> ()
> >
> > +
> >
> > +**/
> >
> > +EFI_STATUS
> >
> > +PlatformBdsForceActiveVga (
> >
> > +  VOID
> >
> > +  )
> >
> > +{
> >
> > +  EFI_STATUS                Status;
> >
> > +  EFI_DEVICE_PATH_PROTOCOL  *DevicePathFirst;
> >
> > +  EFI_DEVICE_PATH_PROTOCOL  *DevicePathSecond;
> >
> > +  EFI_DEVICE_PATH_PROTOCOL  *GopDevicePath;
> >
> > +  EFI_DEVICE_PATH_PROTOCOL  *IGpuDevicePath;
> >
> > +  EFI_DEVICE_PATH_PROTOCOL  *DGpuDevicePath;
> >
> > +
> >
> > +  DEBUG ((EFI_D_INFO, "PlatformBdsForceActiveVga enter\n"));
> >
> > +
> >
> > +  Status           = EFI_SUCCESS;
> >
> > +  DevicePathFirst  = NULL;
> >
> > +  DevicePathSecond = NULL;
> >
> > +  GopDevicePath    = NULL;
> >
> > +  IGpuDevicePath   = NULL;
> >
> > +  DGpuDevicePath   = NULL;
> >
> > +
> >
> > +  //
> >
> > +  // Get device path of one IGPU and one DGPU
> >
> > +  //
> >
> > +  Status = GetVgaDevicePath (&IGpuDevicePath, &DGpuDevicePath);
> >
> > +  ASSERT_EFI_ERROR (Status);
> >
> > +
> >
> > +  if ((IGpuDevicePath == NULL) && (DGpuDevicePath == NULL)) {
> >
> > +    DEBUG ((EFI_D_INFO, "No valid IGPU and DGPU\n"));
> >
> > +    return EFI_UNSUPPORTED;
> >
> > +  }
> >
> > +
> >
> > +  if ((IGpuDevicePath != NULL) && (DGpuDevicePath == NULL)) {
> >
> > +    DEBUG ((EFI_D_INFO, "Only IGPU is valid\n"));
> >
> > +    // DEBUG ((EFI_D_INFO,"Only IGPU is valid, Update IGPU ...\n"));
> >
> > +    DevicePathFirst  = IGpuDevicePath;
> >
> > +    DevicePathSecond = DGpuDevicePath;
> >
> > +    goto UpdateConOut;
> >
> > +  } else if ((IGpuDevicePath == NULL) && (DGpuDevicePath != NULL)) {
> >
> > +    DEBUG ((EFI_D_INFO, "Only DGPU is valid\n"));
> >
> > +    // DEBUG ((EFI_D_INFO,"Only DGPU is valid, Update DGPU ...\n"));
> >
> > +    DevicePathFirst  = DGpuDevicePath;
> >
> > +    DevicePathSecond = IGpuDevicePath;
> >
> > +    goto UpdateConOut;
> >
> > +  } else if ((IGpuDevicePath != NULL) && (DGpuDevicePath != NULL)) {
> >
> > +    DEBUG ((EFI_D_INFO, "DGPU and IGPU are valid, active DGPU\n"));
> >
> > +    // DEBUG ((EFI_D_INFO,"Only DGPU is valid, Update DGPU ...\n"));
> >
> > +    DevicePathFirst  = DGpuDevicePath;
> >
> > +    DevicePathSecond = IGpuDevicePath;
> >
> > +    goto UpdateConOut;
> >
> > +  }
> >
> > +
> >
> > +UpdateConOut:
> >
> > +  DEBUG ((DEBUG_INFO, "Before GetGopDevicePath: ConOutDevicePath is
> > %S\n", ConvertDevicePathToText (DevicePathFirst, FALSE, FALSE)));
> >
> > +  GetGopDevicePath (DevicePathFirst, &GopDevicePath);
> >
> > +  DevicePathFirst = GopDevicePath;
> >
> > +  DEBUG ((DEBUG_INFO, "After GetGopDevicePath: ConOutDevicePath is
> > %S\n", ConvertDevicePathToText (DevicePathFirst, FALSE, FALSE)));
> >
> > +  DEBUG ((DEBUG_INFO, "Exclusive device path is %S\n",
> > ConvertDevicePathToText (DevicePathSecond, FALSE, FALSE)));
> >
> > +
> >
> > +  Status = EfiBootManagerUpdateConsoleVariable (
> >
> > +             ConOut,
> >
> > +             DevicePathFirst,
> >
> > +             DevicePathSecond
> >
> > +             );
> >
> > +  // TODO: Specify iGPU/dGPU.
> >
> > +  EfiBootManagerConnectVideoController (NULL);
> >
> > +  return Status;
> >
> > +}
> >
> > +
> >
> > +/**
> >
> > +  Do the platform specific action before the console is connected.
> >
> > +
> >
> > +  Such as:
> >
> > +    Update console variable;
> >
> > +    Register new Driver#### or Boot####;
> >
> > +    Signal ReadyToLock event.
> >
> > +**/
> >
> > +VOID
> >
> > +EFIAPI
> >
> > +PlatformBootManagerBeforeConsole (
> >
> > +  VOID
> >
> > +  )
> >
> > +{
> >
> > +  EFI_INPUT_KEY                 Enter;
> >
> > +  EFI_INPUT_KEY                 CustomKey;
> >
> > +  EFI_INPUT_KEY                 Down;
> >
> > +  EFI_BOOT_MANAGER_LOAD_OPTION  BootOption;
> >
> > +  EFI_STATUS                    Status;
> >
> > +  UINT64                        OsIndication;
> >
> > +  UINTN                         DataSize;
> >
> > +  UINT32                        Attributes;
> >
> > +  BOOLEAN                       CapsuleUpdateonDisk;
> >
> > +
> >
> > +  Status = gBS->LocateProtocol
> > (&gUniversalPayloadPlatformBootManagerOverrideProtocolGuid, NULL,
> > (VOID **)&mUniversalPayloadPlatformBootManagerOverrideInstance);
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    mUniversalPayloadPlatformBootManagerOverrideInstance = NULL;
> >
> > +  }
> >
> > +
> >
> > +  Status = gRT->GetVariable (
> >
> > +                  L"OsIndications",
> >
> > +                  &gEfiGlobalVariableGuid,
> >
> > +                  &Attributes,
> >
> > +                  &DataSize,
> >
> > +                  &OsIndication
> >
> > +                  );
> >
> > +  if (mUniversalPayloadPlatformBootManagerOverrideInstance != NULL) {
> >
> > +    mUniversalPayloadPlatformBootManagerOverrideInstance-
> > >BeforeConsole ();
> >
> > +    return;
> >
> > +  }
> >
> > +
> >
> > +  //
> >
> > +  // Register ENTER as CONTINUE key
> >
> > +  //
> >
> > +  Enter.ScanCode    = SCAN_NULL;
> >
> > +  Enter.UnicodeChar = CHAR_CARRIAGE_RETURN;
> >
> > +  EfiBootManagerRegisterContinueKeyOption (0, &Enter, NULL);
> >
> > +
> >
> > +  if (FixedPcdGetBool (PcdBootManagerEscape)) {
> >
> > +    //
> >
> > +    // Map Esc to Boot Manager Menu
> >
> > +    //
> >
> > +    CustomKey.ScanCode    = SCAN_ESC;
> >
> > +    CustomKey.UnicodeChar = CHAR_NULL;
> >
> > +  } else {
> >
> > +    //
> >
> > +    // Map Esc to Boot Manager Menu
> >
> > +    //
> >
> > +    CustomKey.ScanCode    = SCAN_F2;
> >
> > +    CustomKey.UnicodeChar = CHAR_NULL;
> >
> > +  }
> >
> > +
> >
> > +  EfiBootManagerGetBootManagerMenu (&BootOption);
> >
> > +  EfiBootManagerAddKeyOptionVariable (NULL,
> > (UINT16)BootOption.OptionNumber, 0, &CustomKey, NULL);
> >
> > +
> >
> > +  //
> >
> > +  // Also add Down key to Boot Manager Menu since some serial terminals
> > don't support F2 key.
> >
> > +  //
> >
> > +  Down.ScanCode    = SCAN_DOWN;
> >
> > +  Down.UnicodeChar = CHAR_NULL;
> >
> > +  EfiBootManagerGetBootManagerMenu (&BootOption);
> >
> > +  EfiBootManagerAddKeyOptionVariable (NULL,
> > (UINT16)BootOption.OptionNumber, 0, &Down, NULL);
> >
> > +  CapsuleUpdateonDisk = (BOOLEAN)((OsIndication &
> > EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED) != 0);
> >
> > +  // Process Capsule in Memory first, before EndOfDxe.
> >
> > +  if ((GetBootModeHob () == BOOT_ON_FLASH_UPDATE) ||
> > CapsuleUpdateonDisk) {
> >
> > +    PlatformBdsForceActiveVga (); // Force enable VGA on Capsule Update.
> >
> > +    ASSERT_EFI_ERROR (BootLogoEnableLogo ());
> >
> > +    Print (
> >
> > +      L"\n"
> >
> > +      L"    Updating system BIOS.....\n"
> >
> > +      L"\n"
> >
> > +      );
> >
> > +    if (CapsuleUpdateonDisk) {
> >
> > +      EfiBootManagerConnectAll (); // Get BlockIo
> >
> > +      CapsuleUpdateViaFileLib ();
> >
> > +    } else {
> >
> > +      ProcessCapsules ();
> >
> > +    }
> >
> > +  }
> >
> > +
> >
> > +  //
> >
> > +  // Install ready to lock.
> >
> > +  // This needs to be done before option rom dispatched.
> >
> > +  //
> >
> > +  InstallReadyToLock ();
> >
> > +
> >
> > +  //
> >
> > +  // Dispatch deferred images after EndOfDxe event and ReadyToLock
> > installation.
> >
> > +  //
> >
> > +  EfiBootManagerDispatchDeferredImages ();
> >
> > +
> >
> > +  PlatformConsoleInit ();
> >
> > +}
> >
> > +
> >
> > +/**
> >
> > +  Do the platform specific action after the console is connected.
> >
> > +
> >
> > +  Such as:
> >
> > +    Dynamically switch output mode;
> >
> > +    Signal console ready platform customized event;
> >
> > +    Run diagnostics like memory testing;
> >
> > +    Connect certain devices;
> >
> > +    Dispatch additional option roms.
> >
> > +**/
> >
> > +VOID
> >
> > +EFIAPI
> >
> > +PlatformBootManagerAfterConsole (
> >
> > +  VOID
> >
> > +  )
> >
> > +{
> >
> > +  EFI_GRAPHICS_OUTPUT_BLT_PIXEL  Black;
> >
> > +  EFI_GRAPHICS_OUTPUT_BLT_PIXEL  White;
> >
> > +  EDKII_PLATFORM_LOGO_PROTOCOL   *PlatformLogo;
> >
> > +  EFI_STATUS                     Status;
> >
> > +  UINT64                         OsIndication;
> >
> > +  UINTN                          DataSize;
> >
> > +  UINT32                         Attributes;
> >
> > +
> >
> > +  if (mUniversalPayloadPlatformBootManagerOverrideInstance != NULL) {
> >
> > +    mUniversalPayloadPlatformBootManagerOverrideInstance-
> >AfterConsole
> > ();
> >
> > +    return;
> >
> > +  }
> >
> > +
> >
> > +  Black.Blue = Black.Green = Black.Red = Black.Reserved = 0;
> >
> > +  White.Blue = White.Green = White.Red = White.Reserved = 0xFF;
> >
> > +
> >
> > +  Status = gBS->LocateProtocol (&gEdkiiPlatformLogoProtocolGuid, NULL,
> > (VOID **)&PlatformLogo);
> >
> > +
> >
> > +  if (!EFI_ERROR (Status)) {
> >
> > +    gST->ConOut->ClearScreen (gST->ConOut);
> >
> > +    BootLogoEnableLogo ();
> >
> > +  }
> >
> > +
> >
> > +  EfiBootManagerConnectAll ();
> >
> > +  EfiBootManagerRefreshAllBootOption ();
> >
> > +
> >
> > +  // Process Capsule in Memory again, after EndOfDxe.
> >
> > +  if (GetBootModeHob () == BOOT_ON_FLASH_UPDATE) {
> >
> > +    ProcessCapsules ();
> >
> > +  }
> >
> > +
> >
> > +  OsIndication = 0;
> >
> > +  Attributes   = 0;
> >
> > +  DataSize     = sizeof (UINT64);
> >
> > +  Status       = gRT->GetVariable (
> >
> > +                        EFI_OS_INDICATIONS_VARIABLE_NAME,
> >
> > +                        &gEfiGlobalVariableGuid,
> >
> > +                        &Attributes,
> >
> > +                        &DataSize,
> >
> > +                        &OsIndication
> >
> > +                        );
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    OsIndication = 0;
> >
> > +  }
> >
> > +
> >
> > +  //
> >
> > +  // Register UEFI Shell
> >
> > +  //
> >
> > +  PlatformRegisterFvBootOption (PcdGetPtr (PcdShellFile), L"UEFI Shell",
> > LOAD_OPTION_ACTIVE);
> >
> > +
> >
> > +  {
> >
> > +    if (FixedPcdGetBool (PcdBootManagerEscape)) {
> >
> > +      Print (
> >
> > +        L"\n"
> >
> > +        L"    Esc or Down      to enter Boot Manager Menu.\n"
> >
> > +        L"    ENTER            to boot directly.\n"
> >
> > +        L"\n"
> >
> > +        );
> >
> > +    } else {
> >
> > +      Print (
> >
> > +        L"\n"
> >
> > +        L"    F2 or Down      to enter Boot Manager Menu.\n"
> >
> > +        L"    ENTER           to boot directly.\n"
> >
> > +        L"\n"
> >
> > +        );
> >
> > +    }
> >
> > +  }
> >
> > +}
> >
> > +
> >
> > +/**
> >
> > +  This function is called each second during the boot manager waits the
> > timeout.
> >
> > +
> >
> > +  @param TimeoutRemain  The remaining timeout.
> >
> > +**/
> >
> > +VOID
> >
> > +EFIAPI
> >
> > +PlatformBootManagerWaitCallback (
> >
> > +  UINT16  TimeoutRemain
> >
> > +  )
> >
> > +{
> >
> > +  if (mUniversalPayloadPlatformBootManagerOverrideInstance != NULL) {
> >
> > +    mUniversalPayloadPlatformBootManagerOverrideInstance-
> >WaitCallback
> > (TimeoutRemain);
> >
> > +  }
> >
> > +
> >
> > +  return;
> >
> > +}
> >
> > +
> >
> > +/**
> >
> > +  The function is called when no boot option could be launched,
> >
> > +  including platform recovery options and options pointing to applications
> >
> > +  built into firmware volumes.
> >
> > +
> >
> > +  If this function returns, BDS attempts to enter an infinite loop.
> >
> > +**/
> >
> > +VOID
> >
> > +EFIAPI
> >
> > +PlatformBootManagerUnableToBoot (
> >
> > +  VOID
> >
> > +  )
> >
> > +{
> >
> > +  if (mUniversalPayloadPlatformBootManagerOverrideInstance != NULL) {
> >
> > +    mUniversalPayloadPlatformBootManagerOverrideInstance-
> >UnableToBoot
> > ();
> >
> > +  }
> >
> > +
> >
> > +  return;
> >
> > +}
> >
> > +
> >
> > +typedef struct {
> >
> > +  UINTN                   Signature;
> >
> > +  LIST_ENTRY              Link;
> >
> > +  EFI_PHYSICAL_ADDRESS    StartAddress;
> >
> > +  UINT64                  Length;
> >
> > +  UINT64                  Capabilities;
> >
> > +} NONTESTED_MEMORY_RANGE;
> >
> > +
> >
> > +//
> >
> > +// This structure records every nontested memory range parsed through
> GCD
> >
> > +// service.
> >
> > +//
> >
> > +#define EFI_NONTESTED_MEMORY_RANGE_SIGNATURE  SIGNATURE_32
> > ('N', 'T', 'M', 'E')
> >
> > +
> >
> > +//
> >
> > +// attributes for reserved memory before it is promoted to system memory
> >
> > +//
> >
> > +#define EFI_MEMORY_PRESENT      0x0100000000000000ULL
> >
> > +#define EFI_MEMORY_INITIALIZED  0x0200000000000000ULL
> >
> > +#define EFI_MEMORY_TESTED       0x0400000000000000ULL
> >
> > +
> >
> > +/**
> >
> > +  Callback function for event group EFI_EVENT_GROUP_READY_TO_BOOT.
> >
> > +  This is used to expose the 4G above memory into system memory table.
> >
> > +
> >
> > +  @param[in]  Event      The Event that is being processed.
> >
> > +  @param[in]  Context    The Event Context.
> >
> > +
> >
> > +**/
> >
> > +VOID
> >
> > +EFIAPI
> >
> > +ExposeOver4GMemoryEventCallback (
> >
> > +  IN EFI_EVENT  Event,
> >
> > +  IN VOID       *Context
> >
> > +  )
> >
> > +{
> >
> > +  NONTESTED_MEMORY_RANGE           *Range;
> >
> > +  BOOLEAN                          NoFound;
> >
> > +  UINTN                            NumberOfDescriptors;
> >
> > +  EFI_GCD_MEMORY_SPACE_DESCRIPTOR  *MemorySpaceMap;
> >
> > +  UINTN                            Index;
> >
> > +  LIST_ENTRY                       *TmpLink;
> >
> > +  LIST_ENTRY                       NonTestedMemRanList;
> >
> > +
> >
> > +  DEBUG ((EFI_D_INFO, "ExposeOver4GMemoryEventCallback\n"));
> >
> > +
> >
> > +  TmpLink = NULL;
> >
> > +  NoFound = TRUE;
> >
> > +
> >
> > +  InitializeListHead (&NonTestedMemRanList);
> >
> > +
> >
> > +  gDS->GetMemorySpaceMap (&NumberOfDescriptors,
> > &MemorySpaceMap);
> >
> > +  for (Index = 0; Index < NumberOfDescriptors; Index++) {
> >
> > +    if ((MemorySpaceMap[Index].GcdMemoryType ==
> > EfiGcdMemoryTypeReserved) &&
> >
> > +        ((MemorySpaceMap[Index].Capabilities & (EFI_MEMORY_PRESENT |
> > EFI_MEMORY_INITIALIZED | EFI_MEMORY_TESTED)) ==
> >
> > +         (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED))
> >
> > +        )
> >
> > +    {
> >
> > +      NoFound = FALSE;
> >
> > +
> >
> > +      gBS->AllocatePool (EfiBootServicesData, sizeof
> > (NONTESTED_MEMORY_RANGE), (VOID **)&Range);
> >
> > +
> >
> > +      Range->Signature    = EFI_NONTESTED_MEMORY_RANGE_SIGNATURE;
> >
> > +      Range->StartAddress = MemorySpaceMap[Index].BaseAddress;
> >
> > +      Range->Length       = MemorySpaceMap[Index].Length;
> >
> > +      Range->Capabilities = MemorySpaceMap[Index].Capabilities;
> >
> > +
> >
> > +      InsertTailList (&NonTestedMemRanList, &Range->Link);
> >
> > +    }
> >
> > +  }
> >
> > +
> >
> > +  if (!NoFound) {
> >
> > +    TmpLink = NonTestedMemRanList.ForwardLink;
> >
> > +
> >
> > +    while (TmpLink != &NonTestedMemRanList) {
> >
> > +      Range = CR (TmpLink, NONTESTED_MEMORY_RANGE, Link,
> > EFI_NONTESTED_MEMORY_RANGE_SIGNATURE);
> >
> > +      gDS->RemoveMemorySpace (Range->StartAddress, Range->Length);
> >
> > +      gDS->AddMemorySpace (
> >
> > +             EfiGcdMemoryTypeSystemMemory,
> >
> > +             Range->StartAddress,
> >
> > +             Range->Length,
> >
> > +             Range->Capabilities &~(EFI_MEMORY_PRESENT |
> > EFI_MEMORY_INITIALIZED | EFI_MEMORY_TESTED |
> > EFI_MEMORY_RUNTIME)
> >
> > +             );
> >
> > +
> >
> > +      TmpLink = TmpLink->ForwardLink;
> >
> > +    }
> >
> > +  }
> >
> > +
> >
> > +  //
> >
> > +  // Make sure the hook ONLY called once.
> >
> > +  //
> >
> > +  if (Event != NULL) {
> >
> > +    gBS->CloseEvent (Event);
> >
> > +  }
> >
> > +}
> >
> > +
> >
> > +/**
> >
> > +  Get/update PcdBootManagerMenuFile from GUID HOB which will be
> > assigned in bootloader.
> >
> > +
> >
> > +  @param  ImageHandle   The firmware allocated handle for the EFI image.
> >
> > +  @param  SystemTable   A pointer to the EFI System Table.
> >
> > +
> >
> > +  @retval EFI_SUCCESS       The entry point is executed successfully.
> >
> > +  @retval other             Some error occurs.
> >
> > +
> >
> > +**/
> >
> > +EFI_STATUS
> >
> > +EFIAPI
> >
> > +PlatformBootManagerLibConstructor (
> >
> > +  IN EFI_HANDLE        ImageHandle,
> >
> > +  IN EFI_SYSTEM_TABLE  *SystemTable
> >
> > +  )
> >
> > +{
> >
> > +  EFI_STATUS                           Status;
> >
> > +  UINTN                                Size;
> >
> > +  VOID                                 *GuidHob;
> >
> > +  UNIVERSAL_PAYLOAD_GENERIC_HEADER     *GenericHeader;
> >
> > +  UNIVERSAL_PAYLOAD_BOOT_MANAGER_MENU
> *BootManagerMenuFile;
> >
> > +
> >
> > +  EFI_EVENT  ExposeOver4GMemoryEvent;
> >
> > +
> >
> > +  Status = gBS->CreateEventEx (
> >
> > +                  EVT_NOTIFY_SIGNAL,
> >
> > +                  TPL_CALLBACK,
> >
> > +                  ExposeOver4GMemoryEventCallback,
> >
> > +                  NULL,
> >
> > +                  &gEfiEventReadyToBootGuid,
> >
> > +                  &ExposeOver4GMemoryEvent
> >
> > +                  );
> >
> > +  ASSERT_EFI_ERROR (Status);
> >
> > +
> >
> > +  GuidHob = GetFirstGuidHob (&gEdkiiBootManagerMenuFileGuid);
> >
> > +
> >
> > +  if (GuidHob == NULL) {
> >
> > +    //
> >
> > +    // If the HOB is not create, the default value of PcdBootManagerMenuFile
> > will be used.
> >
> > +    //
> >
> > +    return EFI_SUCCESS;
> >
> > +  }
> >
> > +
> >
> > +  GenericHeader = (UNIVERSAL_PAYLOAD_GENERIC_HEADER
> > *)GET_GUID_HOB_DATA (GuidHob);
> >
> > +  if ((sizeof (UNIVERSAL_PAYLOAD_GENERIC_HEADER) >
> > GET_GUID_HOB_DATA_SIZE (GuidHob)) || (GenericHeader->Length >
> > GET_GUID_HOB_DATA_SIZE (GuidHob))) {
> >
> > +    return EFI_NOT_FOUND;
> >
> > +  }
> >
> > +
> >
> > +  if (GenericHeader->Revision ==
> > UNIVERSAL_PAYLOAD_BOOT_MANAGER_MENU_REVISION) {
> >
> > +    BootManagerMenuFile =
> (UNIVERSAL_PAYLOAD_BOOT_MANAGER_MENU
> > *)GET_GUID_HOB_DATA (GuidHob);
> >
> > +    if (BootManagerMenuFile->Header.Length <
> > UNIVERSAL_PAYLOAD_SIZEOF_THROUGH_FIELD
> > (UNIVERSAL_PAYLOAD_BOOT_MANAGER_MENU, FileName)) {
> >
> > +      return EFI_NOT_FOUND;
> >
> > +    }
> >
> > +
> >
> > +    Size   = sizeof (BootManagerMenuFile->FileName);
> >
> > +    Status = PcdSetPtrS (PcdBootManagerMenuFile, &Size,
> > &BootManagerMenuFile->FileName);
> >
> > +    ASSERT_EFI_ERROR (Status);
> >
> > +  } else {
> >
> > +    return EFI_NOT_FOUND;
> >
> > +  }
> >
> > +
> >
> > +  return EFI_SUCCESS;
> >
> > +}
> >
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/ChachaniBoardPkg/Library/Capsule/Platfor
> > mBootManagerLib/PlatformBootManager.h
> >
> b/Platform/AMD/VanGoghBoard/ChachaniBoardPkg/Library/Capsule/Platfor
> > mBootManagerLib/PlatformBootManager.h
> >
> > new file mode 100644
> >
> > index 0000000000..0b4b85e7d2
> >
> > --- /dev/null
> >
> > +++
> >
> b/Platform/AMD/VanGoghBoard/ChachaniBoardPkg/Library/Capsule/Platfor
> > mBootManagerLib/PlatformBootManager.h
> >
> > @@ -0,0 +1,159 @@
> >
> > +/** @file
> >
> > +  Implements PlatformBootManager.h
> >
> > +
> >
> > +  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
> >
> > +   Head file for BDS Platform specific code
> >
> > +
> >
> > +Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
> >
> > +SPDX-License-Identifier: BSD-2-Clause-Patent
> >
> > +**/
> >
> > +
> >
> > +#ifndef PLATFORM_BOOT_MANAGER_H_
> >
> > +#define PLATFORM_BOOT_MANAGER_H_
> >
> > +
> >
> > +#include <PiDxe.h>
> >
> > +#include <Protocol/LoadedImage.h>
> >
> > +
> >
> > +#include <Library/DebugLib.h>
> >
> > +#include <Library/BaseMemoryLib.h>
> >
> > +#include <Library/UefiBootServicesTableLib.h>
> >
> > +#include <Library/UefiRuntimeServicesTableLib.h>
> >
> > +#include <Library/MemoryAllocationLib.h>
> >
> > +#include <Library/BaseLib.h>
> >
> > +#include <Library/UefiRuntimeServicesTableLib.h>
> >
> > +#include <Library/UefiLib.h>
> >
> > +#include <Library/UefiBootManagerLib.h>
> >
> > +#include <Library/PcdLib.h>
> >
> > +#include <Library/DevicePathLib.h>
> >
> > +#include <Library/HiiLib.h>
> >
> > +#include <Library/PrintLib.h>
> >
> > +#include <Library/DxeServicesLib.h>
> >
> > +#include <Library/BootLogoLib.h>
> >
> > +#include <Protocol/SmmAccess2.h>
> >
> > +#include <Guid/GlobalVariable.h>
> >
> > +typedef struct {
> >
> > +  EFI_DEVICE_PATH_PROTOCOL    *DevicePath;
> >
> > +  UINTN                       ConnectType;
> >
> > +} PLATFORM_CONSOLE_CONNECT_ENTRY;
> >
> > +
> >
> > +extern PLATFORM_CONSOLE_CONNECT_ENTRY  gPlatformConsole[];
> >
> > +
> >
> > +#define gEndEntire \
> >
> > +  { \
> >
> > +    END_DEVICE_PATH_TYPE,\
> >
> > +    END_ENTIRE_DEVICE_PATH_SUBTYPE,\
> >
> > +    { END_DEVICE_PATH_LENGTH, 0 },\
> >
> > +  }
> >
> > +
> >
> > +#define CONSOLE_OUT  BIT0
> >
> > +#define CONSOLE_IN   BIT1
> >
> > +#define STD_ERROR    BIT2
> >
> > +
> >
> > +#define CLASS_HID          3
> >
> > +#define SUBCLASS_BOOT      1
> >
> > +#define PROTOCOL_KEYBOARD  1
> >
> > +
> >
> > +#define PNPID_DEVICE_PATH_NODE(PnpId) \
> >
> > +  { \
> >
> > +    { \
> >
> > +      ACPI_DEVICE_PATH, \
> >
> > +      ACPI_DP, \
> >
> > +      { \
> >
> > +        (UINT8) (sizeof (ACPI_HID_DEVICE_PATH)), \
> >
> > +        (UINT8) ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8) \
> >
> > +      }, \
> >
> > +    }, \
> >
> > +    EISA_PNP_ID((PnpId)), \
> >
> > +    0 \
> >
> > +  }
> >
> > +
> >
> > +#define gPciRootBridge \
> >
> > +  PNPID_DEVICE_PATH_NODE(0x0A03)
> >
> > +
> >
> > +typedef struct {
> >
> > +  USB_CLASS_DEVICE_PATH       UsbClass;
> >
> > +  EFI_DEVICE_PATH_PROTOCOL    End;
> >
> > +} USB_CLASS_FORMAT_DEVICE_PATH;
> >
> > +
> >
> > +typedef struct {
> >
> > +  VENDOR_DEVICE_PATH    VendorDevicePath;
> >
> > +  UINT32                Instance;
> >
> > +} WIN_NT_VENDOR_DEVICE_PATH_NODE;
> >
> > +
> >
> > +//
> >
> > +// Below is the platform console device path
> >
> > +//
> >
> > +typedef struct {
> >
> > +  VENDOR_DEVICE_PATH                NtBus;
> >
> > +  WIN_NT_VENDOR_DEVICE_PATH_NODE    SerialDevice;
> >
> > +  UART_DEVICE_PATH                  Uart;
> >
> > +  VENDOR_DEVICE_PATH                TerminalType;
> >
> > +  EFI_DEVICE_PATH_PROTOCOL          End;
> >
> > +} NT_ISA_SERIAL_DEVICE_PATH;
> >
> > +
> >
> > +typedef struct {
> >
> > +  VENDOR_DEVICE_PATH                NtBus;
> >
> > +  WIN_NT_VENDOR_DEVICE_PATH_NODE    NtGopDevice;
> >
> > +  EFI_DEVICE_PATH_PROTOCOL          End;
> >
> > +} NT_PLATFORM_GOP_DEVICE_PATH;
> >
> > +
> >
> > +extern USB_CLASS_FORMAT_DEVICE_PATH
> gUsbClassKeyboardDevicePath;
> >
> > +
> >
> > +/**
> >
> > +  Use SystemTable Conout to stop video based Simple Text Out consoles
> from
> > going
> >
> > +  to the video device. Put up LogoFile on every video device that is a console.
> >
> > +
> >
> > +  @param[in]  LogoFile   File name of logo to display on the center of the
> > screen.
> >
> > +
> >
> > +  @retval EFI_SUCCESS     ConsoleControl has been flipped to graphics and
> > logo displayed.
> >
> > +  @retval EFI_UNSUPPORTED Logo not found
> >
> > +
> >
> > +**/
> >
> > +EFI_STATUS
> >
> > +PlatformBootManagerEnableQuietBoot (
> >
> > +  IN  EFI_GUID  *LogoFile
> >
> > +  );
> >
> > +
> >
> > +/**
> >
> > +  Use SystemTable Conout to turn on video based Simple Text Out consoles.
> > The
> >
> > +  Simple Text Out screens will now be synced up with all non video output
> > devices
> >
> > +
> >
> > +  @retval EFI_SUCCESS     UGA devices are back in text mode and synced up.
> >
> > +
> >
> > +**/
> >
> > +EFI_STATUS
> >
> > +PlatformBootManagerDisableQuietBoot (
> >
> > +  VOID
> >
> > +  );
> >
> > +
> >
> > +/**
> >
> > +  Show progress bar with title above it. It only works in Graphics mode.
> >
> > +
> >
> > +  @param TitleForeground Foreground color for Title.
> >
> > +  @param TitleBackground Background color for Title.
> >
> > +  @param Title           Title above progress bar.
> >
> > +  @param ProgressColor   Progress bar color.
> >
> > +  @param Progress        Progress (0-100)
> >
> > +  @param PreviousValue   The previous value of the progress.
> >
> > +
> >
> > +  @retval  EFI_STATUS       Success update the progress bar
> >
> > +
> >
> > +**/
> >
> > +EFI_STATUS
> >
> > +PlatformBootManagerShowProgress (
> >
> > +  IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL  TitleForeground,
> >
> > +  IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL  TitleBackground,
> >
> > +  IN CHAR16                         *Title,
> >
> > +  IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL  ProgressColor,
> >
> > +  IN UINTN                          Progress,
> >
> > +  IN UINTN                          PreviousValue
> >
> > +  );
> >
> > +
> >
> > +#endif // _PLATFORM_BOOT_MANAGER_H
> >
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/ChachaniBoardPkg/Library/Capsule/Platfor
> > mBootManagerLib/PlatformBootManagerLib.inf
> >
> b/Platform/AMD/VanGoghBoard/ChachaniBoardPkg/Library/Capsule/Platfor
> > mBootManagerLib/PlatformBootManagerLib.inf
> >
> > new file mode 100644
> >
> > index 0000000000..db58d94301
> >
> > --- /dev/null
> >
> > +++
> >
> b/Platform/AMD/VanGoghBoard/ChachaniBoardPkg/Library/Capsule/Platfor
> > mBootManagerLib/PlatformBootManagerLib.inf
> >
> > @@ -0,0 +1,96 @@
> >
> > +## @file
> >
> > +# Platform Boot Manager Lib Module
> >
> > +#
> >
> > +# 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
> >
> > +#  Include all platform action which can be customized by IBV/OEM.
> >
> > +#
> >
> > +#  Copyright (c) 2012 - 2021, Intel Corporation. All rights reserved.<BR>
> >
> > +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> >
> > +#
> >
> > +##
> >
> > +
> >
> > +[Defines]
> >
> > +  INF_VERSION                    = 0x00010005
> >
> > +  BASE_NAME                      = PlatformBootManagerLib
> >
> > +  FILE_GUID                      = 9455F0BD-2037-488A-8899-56CB72A44A03
> >
> > +  MODULE_TYPE                    = DXE_DRIVER
> >
> > +  VERSION_STRING                 = 1.0
> >
> > +  LIBRARY_CLASS                  = PlatformBootManagerLib|DXE_DRIVER
> >
> > +  CONSTRUCTOR                    = PlatformBootManagerLibConstructor
> >
> > +
> >
> > +#
> >
> > +# The following information is for reference only and not required by the
> build
> > tools.
> >
> > +#
> >
> > +#  VALID_ARCHITECTURES           = IA32 X64 EBC
> >
> > +#
> >
> > +
> >
> > +[Sources]
> >
> > +  PlatformData.c
> >
> > +  PlatformConsole.c
> >
> > +  PlatformConsole.h
> >
> > +  PlatformBootManager.c
> >
> > +  PlatformBootManager.h
> >
> > +
> >
> > +[Packages]
> >
> > +  MdePkg/MdePkg.dec
> >
> > +  MdeModulePkg/MdeModulePkg.dec
> >
> > +  UefiPayloadPkg/UefiPayloadPkg.dec
> >
> > +  AgesaPublic/AgesaPublic.dec
> >
> > +  VanGoghCommonPkg/AmdCommonPkg.dec
> >
> > +  ChachaniBoardPkg/Project.dec
> >
> > +
> >
> > +[LibraryClasses]
> >
> > +  BaseLib
> >
> > +  UefiBootServicesTableLib
> >
> > +  UefiRuntimeServicesTableLib
> >
> > +  UefiLib
> >
> > +  UefiBootManagerLib
> >
> > +  BootLogoLib
> >
> > +  PcdLib
> >
> > +  DxeServicesLib
> >
> > +  DxeServicesTableLib
> >
> > +  MemoryAllocationLib
> >
> > +  DevicePathLib
> >
> > +  HiiLib
> >
> > +  PrintLib
> >
> > +  PlatformHookLib
> >
> > +  HobLib
> >
> > +  DebugLib
> >
> > +  CapsuleLib
> >
> > +  CapsuleHookLib
> >
> > +
> >
> > +[Guids]
> >
> > +  gEfiEndOfDxeEventGroupGuid
> >
> > +  gEdkiiBootManagerMenuFileGuid
> >
> > +  gEfiEventReadyToBootGuid
> >
> > +
> >
> > +[Protocols]
> >
> > +  gEfiGenericMemTestProtocolGuid  ## CONSUMES
> >
> > +  gEfiGraphicsOutputProtocolGuid  ## CONSUMES
> >
> > +  gEfiUgaDrawProtocolGuid         ## CONSUMES
> >
> > +  gEfiBootLogoProtocolGuid        ## CONSUMES
> >
> > +  gEfiDxeSmmReadyToLockProtocolGuid
> >
> > +  gEfiSmmAccess2ProtocolGuid
> >
> > +  gUniversalPayloadPlatformBootManagerOverrideProtocolGuid
> >
> > +  gEfiSerialIoProtocolGuid
> >
> > +  gEfiPciRootBridgeIoProtocolGuid
> >
> > +  gAmdCpmAllPciIoProtocolsInstalledProtocolGuid
> >
> > +
> >
> > +[Pcd]
> >
> > +  gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut
> >
> > +  gEfiMdePkgTokenSpaceGuid.PcdUgaConsumeSupport
> >
> > +  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutRow
> >
> > +  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutColumn
> >
> > +  gEfiMdeModulePkgTokenSpaceGuid.PcdConInConnectOnDemand
> >
> > +  gUefiPayloadPkgTokenSpaceGuid.PcdShellFile
> >
> > +  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate
> >
> > +  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits
> >
> > +  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity
> >
> > +  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits
> >
> > +  gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile
> >
> > +  gUefiPayloadPkgTokenSpaceGuid.PcdBootManagerEscape
> >
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/ChachaniBoardPkg/Library/Capsule/Platfor
> > mBootManagerLib/PlatformConsole.c
> >
> b/Platform/AMD/VanGoghBoard/ChachaniBoardPkg/Library/Capsule/Platfor
> > mBootManagerLib/PlatformConsole.c
> >
> > new file mode 100644
> >
> > index 0000000000..0715fcc86e
> >
> > --- /dev/null
> >
> > +++
> >
> b/Platform/AMD/VanGoghBoard/ChachaniBoardPkg/Library/Capsule/Platfor
> > mBootManagerLib/PlatformConsole.c
> >
> > @@ -0,0 +1,504 @@
> >
> > +/** @file
> >
> > +  Implements PlatformConsole.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
> >
> > +This file include all platform action which can be customized by IBV/OEM.
> >
> > +
> >
> > +Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> >
> > +SPDX-License-Identifier: BSD-2-Clause-Patent
> >
> > +
> >
> > +**/
> >
> > +
> >
> > +#include "PlatformBootManager.h"
> >
> > +#include "PlatformConsole.h"
> >
> > +#include <Guid/SerialPortLibVendor.h>
> >
> > +
> >
> > +#define PCI_DEVICE_PATH_NODE(Func, Dev) \
> >
> > +  { \
> >
> > +    { \
> >
> > +      HARDWARE_DEVICE_PATH, \
> >
> > +      HW_PCI_DP, \
> >
> > +      { \
> >
> > +        (UINT8) (sizeof (PCI_DEVICE_PATH)), \
> >
> > +        (UINT8) ((sizeof (PCI_DEVICE_PATH)) >> 8) \
> >
> > +      } \
> >
> > +    }, \
> >
> > +    (Func), \
> >
> > +    (Dev) \
> >
> > +  }
> >
> > +
> >
> > +#define PNPID_DEVICE_PATH_NODE(PnpId) \
> >
> > +  { \
> >
> > +    { \
> >
> > +      ACPI_DEVICE_PATH, \
> >
> > +      ACPI_DP, \
> >
> > +      { \
> >
> > +        (UINT8) (sizeof (ACPI_HID_DEVICE_PATH)), \
> >
> > +        (UINT8) ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8) \
> >
> > +      }, \
> >
> > +    }, \
> >
> > +    EISA_PNP_ID((PnpId)), \
> >
> > +    0 \
> >
> > +  }
> >
> > +
> >
> > +#define gPnp16550ComPort \
> >
> > +  PNPID_DEVICE_PATH_NODE(0x0501)
> >
> > +
> >
> > +#define gPnpPs2Keyboard \
> >
> > +  PNPID_DEVICE_PATH_NODE(0x0303)
> >
> > +
> >
> > +#define gPcAnsiTerminal \
> >
> > +  { \
> >
> > +    { \
> >
> > +      MESSAGING_DEVICE_PATH, \
> >
> > +      MSG_VENDOR_DP, \
> >
> > +      { \
> >
> > +        (UINT8) (sizeof (VENDOR_DEVICE_PATH)), \
> >
> > +        (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8) \
> >
> > +      } \
> >
> > +    }, \
> >
> > +    DEVICE_PATH_MESSAGING_PC_ANSI \
> >
> > +  }
> >
> > +
> >
> > +ACPI_HID_DEVICE_PATH  gPnpPs2KeyboardDeviceNode  =
> > gPnpPs2Keyboard;
> >
> > +ACPI_HID_DEVICE_PATH  gPnp16550ComPortDeviceNode =
> > gPnp16550ComPort;
> >
> > +VENDOR_DEVICE_PATH    gTerminalTypeDeviceNode    = gPcAnsiTerminal;
> >
> > +
> >
> > +BOOLEAN  mDetectDisplayOnly;
> >
> > +
> >
> > +/**
> >
> > +  Add IsaKeyboard to ConIn.
> >
> > +
> >
> > +  @param[in] DeviceHandle  Handle of the LPC Bridge device.
> >
> > +
> >
> > +  @retval EFI_SUCCESS  IsaKeyboard on the LPC bridge have been added to
> > ConIn.
> >
> > +  @return              Error codes, due to EFI_DEVICE_PATH_PROTOCOL missing
> >
> > +                       from DeviceHandle.
> >
> > +**/
> >
> > +EFI_STATUS
> >
> > +PrepareLpcBridgeDevicePath (
> >
> > +  IN EFI_HANDLE  DeviceHandle
> >
> > +  )
> >
> > +{
> >
> > +  EFI_STATUS                Status;
> >
> > +  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
> >
> > +
> >
> > +  DevicePath = NULL;
> >
> > +  Status     = gBS->HandleProtocol (
> >
> > +                      DeviceHandle,
> >
> > +                      &gEfiDevicePathProtocolGuid,
> >
> > +                      (VOID *)&DevicePath
> >
> > +                      );
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  //
> >
> > +  // Register Keyboard
> >
> > +  //
> >
> > +  DevicePath = AppendDevicePathNode (DevicePath,
> > (EFI_DEVICE_PATH_PROTOCOL *)&gPnpPs2KeyboardDeviceNode);
> >
> > +  EfiBootManagerUpdateConsoleVariable (ConIn, DevicePath, NULL);
> >
> > +  return EFI_SUCCESS;
> >
> > +}
> >
> > +
> >
> > +/**
> >
> > +  Return the GOP device path in the platform.
> >
> > +
> >
> > +  @param[in]   PciDevicePath - Device path for the PCI graphics device.
> >
> > +  @param[out]  GopDevicePath - Return the device path with GOP installed.
> >
> > +
> >
> > +  @retval EFI_SUCCESS  - PCI VGA is added to ConOut.
> >
> > +  @retval EFI_INVALID_PARAMETER   - The device path parameter is invalid.
> >
> > +  @retval EFI_STATUS   - No GOP device found.
> >
> > +**/
> >
> > +EFI_STATUS
> >
> > +GetGopDevicePath (
> >
> > +  IN  EFI_DEVICE_PATH_PROTOCOL  *PciDevicePath,
> >
> > +  OUT EFI_DEVICE_PATH_PROTOCOL  **GopDevicePath
> >
> > +  )
> >
> > +{
> >
> > +  UINTN                     Index;
> >
> > +  EFI_STATUS                Status;
> >
> > +  EFI_HANDLE                PciDeviceHandle;
> >
> > +  EFI_DEVICE_PATH_PROTOCOL  *TempDevicePath;
> >
> > +  EFI_DEVICE_PATH_PROTOCOL  *TempPciDevicePath;
> >
> > +  UINTN                     GopHandleCount;
> >
> > +  EFI_HANDLE                *GopHandleBuffer;
> >
> > +
> >
> > +  if ((PciDevicePath == NULL) || (GopDevicePath == NULL)) {
> >
> > +    return EFI_INVALID_PARAMETER;
> >
> > +  }
> >
> > +
> >
> > +  //
> >
> > +  // Initialize the GopDevicePath to be PciDevicePath
> >
> > +  //
> >
> > +  *GopDevicePath    = PciDevicePath;
> >
> > +  TempPciDevicePath = PciDevicePath;
> >
> > +
> >
> > +  Status = gBS->LocateDevicePath (
> >
> > +                  &gEfiDevicePathProtocolGuid,
> >
> > +                  &TempPciDevicePath,
> >
> > +                  &PciDeviceHandle
> >
> > +                  );
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  gBS->ConnectController (PciDeviceHandle, NULL, NULL, FALSE);
> >
> > +
> >
> > +  Status = gBS->LocateHandleBuffer (
> >
> > +                  ByProtocol,
> >
> > +                  &gEfiGraphicsOutputProtocolGuid,
> >
> > +                  NULL,
> >
> > +                  &GopHandleCount,
> >
> > +                  &GopHandleBuffer
> >
> > +                  );
> >
> > +  if (!EFI_ERROR (Status)) {
> >
> > +    //
> >
> > +    // Add all the child handles as possible Console Device
> >
> > +    //
> >
> > +    for (Index = 0; Index < GopHandleCount; Index++) {
> >
> > +      Status = gBS->HandleProtocol (GopHandleBuffer[Index],
> > &gEfiDevicePathProtocolGuid, (VOID *)&TempDevicePath);
> >
> > +      if (EFI_ERROR (Status)) {
> >
> > +        continue;
> >
> > +      }
> >
> > +
> >
> > +      if (CompareMem (
> >
> > +            PciDevicePath,
> >
> > +            TempDevicePath,
> >
> > +            GetDevicePathSize (PciDevicePath) - END_DEVICE_PATH_LENGTH
> >
> > +            ) == 0)
> >
> > +      {
> >
> > +        //
> >
> > +        // In current implementation, we only enable one of the child handles
> >
> > +        // as console device, i.e. sotre one of the child handle's device
> >
> > +        // path to variable "ConOut"
> >
> > +        // In future, we could select all child handles to be console device
> >
> > +        //
> >
> > +        *GopDevicePath = TempDevicePath;
> >
> > +
> >
> > +        //
> >
> > +        // Delete the PCI device's path that added by
> > GetPlugInPciVgaDevicePath()
> >
> > +        // Add the integrity GOP device path.
> >
> > +        //
> >
> > +        EfiBootManagerUpdateConsoleVariable (ConOut, NULL,
> PciDevicePath);
> >
> > +        EfiBootManagerUpdateConsoleVariable (ConOut, TempDevicePath,
> > NULL);
> >
> > +      }
> >
> > +    }
> >
> > +
> >
> > +    gBS->FreePool (GopHandleBuffer);
> >
> > +  }
> >
> > +
> >
> > +  return EFI_SUCCESS;
> >
> > +}
> >
> > +
> >
> > +/**
> >
> > +  Add PCI VGA to ConOut, ConIn, ErrOut.
> >
> > +
> >
> > +  @param[in]  DeviceHandle - Handle of PciIo protocol.
> >
> > +
> >
> > +  @retval EFI_SUCCESS  - PCI VGA is added to ConOut.
> >
> > +  @retval EFI_STATUS   - No PCI VGA device is added.
> >
> > +
> >
> > +**/
> >
> > +EFI_STATUS
> >
> > +PreparePciVgaDevicePath (
> >
> > +  IN EFI_HANDLE  DeviceHandle
> >
> > +  )
> >
> > +{
> >
> > +  EFI_STATUS                Status;
> >
> > +  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
> >
> > +  EFI_DEVICE_PATH_PROTOCOL  *GopDevicePath;
> >
> > +
> >
> > +  DevicePath = NULL;
> >
> > +  Status     = gBS->HandleProtocol (
> >
> > +                      DeviceHandle,
> >
> > +                      &gEfiDevicePathProtocolGuid,
> >
> > +                      (VOID *)&DevicePath
> >
> > +                      );
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  GetGopDevicePath (DevicePath, &GopDevicePath);
> >
> > +  DevicePath = GopDevicePath;
> >
> > +
> >
> > +  EfiBootManagerUpdateConsoleVariable (ConOut, DevicePath, NULL);
> >
> > +
> >
> > +  return EFI_SUCCESS;
> >
> > +}
> >
> > +
> >
> > +/**
> >
> > +  For every PCI instance execute a callback function.
> >
> > +
> >
> > +  @param[in]  Id                 - The protocol GUID for callback
> >
> > +  @param[in]  CallBackFunction   - The callback function
> >
> > +
> >
> > +  @retval EFI_STATUS - Callback function failed.
> >
> > +
> >
> > +**/
> >
> > +EFI_STATUS
> >
> > +EFIAPI
> >
> > +VisitAllInstancesOfProtocol (
> >
> > +  IN EFI_GUID                           *Id,
> >
> > +  IN SIMPLE_PROTOCOL_INSTANCE_CALLBACK  CallBackFunction
> >
> > +  )
> >
> > +{
> >
> > +  EFI_STATUS  Status;
> >
> > +  UINTN       HandleCount;
> >
> > +  EFI_HANDLE  *HandleBuffer;
> >
> > +  UINTN       Index;
> >
> > +  VOID        *Instance;
> >
> > +
> >
> > +  //
> >
> > +  // Start to check all the PciIo to find all possible device
> >
> > +  //
> >
> > +  HandleCount  = 0;
> >
> > +  HandleBuffer = NULL;
> >
> > +  Status       = gBS->LocateHandleBuffer (
> >
> > +                        ByProtocol,
> >
> > +                        Id,
> >
> > +                        NULL,
> >
> > +                        &HandleCount,
> >
> > +                        &HandleBuffer
> >
> > +                        );
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  for (Index = 0; Index < HandleCount; Index++) {
> >
> > +    Status = gBS->HandleProtocol (HandleBuffer[Index], Id, &Instance);
> >
> > +    if (EFI_ERROR (Status)) {
> >
> > +      continue;
> >
> > +    }
> >
> > +
> >
> > +    Status = (*CallBackFunction)(
> >
> > +  HandleBuffer[Index],
> >
> > +  Instance
> >
> > +  );
> >
> > +  }
> >
> > +
> >
> > +  gBS->FreePool (HandleBuffer);
> >
> > +
> >
> > +  return EFI_SUCCESS;
> >
> > +}
> >
> > +
> >
> > +/**
> >
> > +  Do platform specific PCI Device check and add them to
> >
> > +  ConOut, ConIn, ErrOut.
> >
> > +
> >
> > +  @param[in]  Handle    - Handle of PCI device instance
> >
> > +  @param[in]  Instance  - The instance of PCI device
> >
> > +
> >
> > +  @retval EFI_SUCCESS - PCI Device check and Console variable update
> > successfully.
> >
> > +  @retval EFI_STATUS - PCI Device check or Console variable update fail.
> >
> > +
> >
> > +**/
> >
> > +EFI_STATUS
> >
> > +EFIAPI
> >
> > +DetectAndPreparePlatformPciDevicePath (
> >
> > +  IN EFI_HANDLE  Handle,
> >
> > +  IN VOID        *Instance
> >
> > +  )
> >
> > +{
> >
> > +  EFI_STATUS           Status;
> >
> > +  EFI_PCI_IO_PROTOCOL  *PciIo;
> >
> > +  PCI_TYPE00           Pci;
> >
> > +
> >
> > +  EFI_HANDLE  CPMHandle;
> >
> > +
> >
> > +  PciIo = (EFI_PCI_IO_PROTOCOL *)Instance;
> >
> > +
> >
> > +  //
> >
> > +  // Check for all PCI device
> >
> > +  //
> >
> > +  Status = PciIo->Pci.Read (
> >
> > +                        PciIo,
> >
> > +                        EfiPciIoWidthUint32,
> >
> > +                        0,
> >
> > +                        sizeof (Pci) / sizeof (UINT32),
> >
> > +                        &Pci
> >
> > +                        );
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  Status = PciIo->Attributes (
> >
> > +                    PciIo,
> >
> > +                    EfiPciIoAttributeOperationEnable,
> >
> > +                    EFI_PCI_DEVICE_ENABLE,
> >
> > +                    NULL
> >
> > +                    );
> >
> > +  ASSERT_EFI_ERROR (Status);
> >
> > +
> >
> > +  if (!mDetectDisplayOnly) {
> >
> > +    //
> >
> > +    // Here we decide whether it is LPC Bridge
> >
> > +    //
> >
> > +    if ((IS_PCI_LPC (&Pci)) ||
> >
> > +        ((IS_PCI_ISA_PDECODE (&Pci)) &&
> >
> > +         (Pci.Hdr.VendorId == 0x8086)
> >
> > +        )
> >
> > +        )
> >
> > +    {
> >
> > +      //
> >
> > +      // Add IsaKeyboard to ConIn,
> >
> > +      // add IsaSerial to ConOut, ConIn, ErrOut
> >
> > +      //
> >
> > +      DEBUG ((DEBUG_INFO, "Found LPC Bridge device\n"));
> >
> > +      PrepareLpcBridgeDevicePath (Handle);
> >
> > +      return EFI_SUCCESS;
> >
> > +    }
> >
> > +  }
> >
> > +
> >
> > +  //
> >
> > +  // Enable all display devices
> >
> > +  //
> >
> > +  if (IS_PCI_DISPLAY (&Pci)) {
> >
> > +    //
> >
> > +    // Add them to ConOut.
> >
> > +    //
> >
> > +    DEBUG ((DEBUG_INFO, "Found PCI Display device\n"));
> >
> > +    EfiBootManagerConnectVideoController (Handle);
> >
> > +    //
> >
> > +    // At this point, all the PCI_IO protocols are installed completely.
> >
> > +    // Install gAmdCpmAllPciIoProtocolsInstalledProtocolGuid protocol for
> > AmdCpmDisplayFeature DXE driver.
> >
> > +    //
> >
> > +    CPMHandle = NULL;
> >
> > +    Status    = gBS->InstallProtocolInterface (
> >
> > +                       &CPMHandle,
> >
> > +                       &gAmdCpmAllPciIoProtocolsInstalledProtocolGuid,
> >
> > +                       EFI_NATIVE_INTERFACE,
> >
> > +                       NULL
> >
> > +                       );
> >
> > +    ASSERT_EFI_ERROR (Status);
> >
> > +    DEBUG ((EFI_D_INFO, "InstallProtocolInterface
> > gAmdCpmAllPciIoProtocolsInstalledProtocolGuid %r\n", Status));
> >
> > +    return EFI_SUCCESS;
> >
> > +  }
> >
> > +
> >
> > +  return Status;
> >
> > +}
> >
> > +
> >
> > +/**
> >
> > +  For every Serial Io instance, add it to ConOut, ConIn, ErrOut.
> >
> > +
> >
> > +  @param[in]  Handle     - The Serial Io device handle
> >
> > +  @param[in]  Instance   - The instance of the SerialIo protocol
> >
> > +
> >
> > +  @retval EFI_STATUS - Callback function failed.
> >
> > +
> >
> > +**/
> >
> > +EFI_STATUS
> >
> > +EFIAPI
> >
> > +AddDevicePathForOneSerialIoInstance (
> >
> > +  IN EFI_HANDLE  Handle,
> >
> > +  IN VOID        *Instance
> >
> > +  )
> >
> > +{
> >
> > +  EFI_STATUS                Status;
> >
> > +  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
> >
> > +
> >
> > +  DevicePath = NULL;
> >
> > +  Status     = gBS->HandleProtocol (
> >
> > +                      Handle,
> >
> > +                      &gEfiDevicePathProtocolGuid,
> >
> > +                      (VOID *)&DevicePath
> >
> > +                      );
> >
> > +  DevicePath = AppendDevicePathNode (DevicePath,
> > (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode);
> >
> > +
> >
> > +  EfiBootManagerUpdateConsoleVariable (ConOut, DevicePath, NULL);
> >
> > +  EfiBootManagerUpdateConsoleVariable (ConIn, DevicePath, NULL);
> >
> > +  EfiBootManagerUpdateConsoleVariable (ErrOut, DevicePath, NULL);
> >
> > +  return Status;
> >
> > +}
> >
> > +
> >
> > +/**
> >
> > +  Do platform specific PCI Device check and add them to ConOut, ConIn,
> > ErrOut
> >
> > +
> >
> > +  @param[in]  DetectDisplayOnly - Only detect display device if it's TRUE.
> >
> > +
> >
> > +  @retval EFI_SUCCESS - PCI Device check and Console variable update
> > successfully.
> >
> > +  @retval EFI_STATUS - PCI Device check or Console variable update fail.
> >
> > +
> >
> > +**/
> >
> > +EFI_STATUS
> >
> > +DetectAndPreparePlatformPciDevicePaths (
> >
> > +  BOOLEAN  DetectDisplayOnly
> >
> > +  )
> >
> > +{
> >
> > +  EFI_STATUS  Status;
> >
> > +
> >
> > +  mDetectDisplayOnly = DetectDisplayOnly;
> >
> > +
> >
> > +  EfiBootManagerUpdateConsoleVariable (
> >
> > +    ConIn,
> >
> > +    (EFI_DEVICE_PATH_PROTOCOL *)&gUsbClassKeyboardDevicePath,
> >
> > +    NULL
> >
> > +    );
> >
> > +
> >
> > +  VisitAllInstancesOfProtocol (
> >
> > +    &gEfiSerialIoProtocolGuid,
> >
> > +    AddDevicePathForOneSerialIoInstance
> >
> > +    );
> >
> > +
> >
> > +  Status = VisitAllInstancesOfProtocol (
> >
> > +             &gEfiPciIoProtocolGuid,
> >
> > +             DetectAndPreparePlatformPciDevicePath
> >
> > +             );
> >
> > +  return Status;
> >
> > +}
> >
> > +
> >
> > +/**
> >
> > +  The function will connect one root bridge
> >
> > +
> >
> > +  @param[in]  Handle     - The root bridge handle
> >
> > +  @param[in]  Instance   - The instance of the root bridge
> >
> > +
> >
> > +  @return EFI_SUCCESS      Connect RootBridge successfully.
> >
> > +
> >
> > +**/
> >
> > +EFI_STATUS
> >
> > +EFIAPI
> >
> > +ConnectOneRootBridge (
> >
> > +  IN EFI_HANDLE  Handle,
> >
> > +  IN VOID        *Instance
> >
> > +  )
> >
> > +{
> >
> > +  EFI_STATUS  Status;
> >
> > +
> >
> > +  Status = gBS->ConnectController (Handle, NULL, NULL, FALSE);
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  return EFI_SUCCESS;
> >
> > +}
> >
> > +
> >
> > +/**
> >
> > +  Platform console init. Include the platform firmware vendor, revision
> >
> > +  and so crc check.
> >
> > +
> >
> > +**/
> >
> > +VOID
> >
> > +EFIAPI
> >
> > +PlatformConsoleInit (
> >
> > +  VOID
> >
> > +  )
> >
> > +{
> >
> > +  VisitAllInstancesOfProtocol (
> >
> > +    &gEfiPciRootBridgeIoProtocolGuid,
> >
> > +    ConnectOneRootBridge
> >
> > +    );
> >
> > +
> >
> > +  //
> >
> > +  // Do platform specific PCI Device check and add them to ConOut, ConIn,
> > ErrOut
> >
> > +  //
> >
> > +  DetectAndPreparePlatformPciDevicePaths (FALSE);
> >
> > +}
> >
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/ChachaniBoardPkg/Library/Capsule/Platfor
> > mBootManagerLib/PlatformConsole.h
> >
> b/Platform/AMD/VanGoghBoard/ChachaniBoardPkg/Library/Capsule/Platfor
> > mBootManagerLib/PlatformConsole.h
> >
> > new file mode 100644
> >
> > index 0000000000..a43583fb17
> >
> > --- /dev/null
> >
> > +++
> >
> b/Platform/AMD/VanGoghBoard/ChachaniBoardPkg/Library/Capsule/Platfor
> > mBootManagerLib/PlatformConsole.h
> >
> > @@ -0,0 +1,78 @@
> >
> > +/** @file
> >
> > +  Implements PlatformConsole.h
> >
> > +
> >
> > +  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
> >
> > +Head file for BDS Platform specific code
> >
> > +
> >
> > +Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> >
> > +SPDX-License-Identifier: BSD-2-Clause-Patent
> >
> > +**/
> >
> > +
> >
> > +#ifndef PLATFORM_CONSOLE_H_
> >
> > +#define PLATFORM_CONSOLE_H_
> >
> > +
> >
> > +#include <PiDxe.h>
> >
> > +#include <IndustryStandard/Pci.h>
> >
> > +#include <Library/DebugLib.h>
> >
> > +#include <Library/BaseMemoryLib.h>
> >
> > +#include <Library/UefiBootServicesTableLib.h>
> >
> > +#include <Library/MemoryAllocationLib.h>
> >
> > +#include <Library/BaseLib.h>
> >
> > +#include <Library/PcdLib.h>
> >
> > +#include <Library/UefiLib.h>
> >
> > +#include <Library/DevicePathLib.h>
> >
> > +#include <Protocol/PciIo.h>
> >
> > +
> >
> > +#define IS_PCI_ISA_PDECODE(_p)  IS_CLASS3 (_p, PCI_CLASS_BRIDGE,
> > PCI_CLASS_BRIDGE_ISA_PDECODE, 0)
> >
> > +
> >
> > +//
> >
> > +// Type definitions
> >
> > +//
> >
> > +
> >
> > +//
> >
> > +// Platform Root Bridge
> >
> > +//
> >
> > +typedef struct {
> >
> > +  ACPI_HID_DEVICE_PATH        PciRootBridge;
> >
> > +  EFI_DEVICE_PATH_PROTOCOL    End;
> >
> > +} PLATFORM_ROOT_BRIDGE_DEVICE_PATH;
> >
> > +
> >
> > +typedef
> >
> > +EFI_STATUS
> >
> > +(EFIAPI *SIMPLE_PROTOCOL_INSTANCE_CALLBACK)(
> >
> > +  IN EFI_HANDLE            Handle,
> >
> > +  IN VOID                 *Instance
> >
> > +  );
> >
> > +
> >
> > +/**
> >
> > +  @param[in]  Handle - Handle of PCI device instance
> >
> > +  @param[in]  PciIo - PCI IO protocol instance
> >
> > +  @param[in]  Pci - PCI Header register block
> >
> > +**/
> >
> > +typedef
> >
> > +EFI_STATUS
> >
> > +(EFIAPI *VISIT_PCI_INSTANCE_CALLBACK)(
> >
> > +  IN EFI_HANDLE           Handle,
> >
> > +  IN EFI_PCI_IO_PROTOCOL  *PciIo,
> >
> > +  IN PCI_TYPE00           *Pci
> >
> > +  );
> >
> > +
> >
> > +/**
> >
> > +  Platform console init. Include the platform firmware vendor, revision
> >
> > +  and so crc check.
> >
> > +
> >
> > +**/
> >
> > +VOID
> >
> > +EFIAPI
> >
> > +PlatformConsoleInit (
> >
> > +  VOID
> >
> > +  );
> >
> > +
> >
> > +#endif
> >
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/ChachaniBoardPkg/Library/Capsule/Platfor
> > mBootManagerLib/PlatformData.c
> >
> b/Platform/AMD/VanGoghBoard/ChachaniBoardPkg/Library/Capsule/Platfor
> > mBootManagerLib/PlatformData.c
> >
> > new file mode 100644
> >
> > index 0000000000..5f4cba87a7
> >
> > --- /dev/null
> >
> > +++
> >
> b/Platform/AMD/VanGoghBoard/ChachaniBoardPkg/Library/Capsule/Platfor
> > mBootManagerLib/PlatformData.c
> >
> > @@ -0,0 +1,48 @@
> >
> > +/** @file
> >
> > +  Implements PlatformData.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
> >
> > +  Defined the platform specific device path which will be filled to
> >
> > +  ConIn/ConOut variables.
> >
> > +
> >
> > +Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> >
> > +SPDX-License-Identifier: BSD-2-Clause-Patent
> >
> > +**/
> >
> > +
> >
> > +#include "PlatformBootManager.h"
> >
> > +
> >
> > +///
> >
> > +/// Predefined platform default console device path
> >
> > +///
> >
> > +GLOBAL_REMOVE_IF_UNREFERENCED
> > PLATFORM_CONSOLE_CONNECT_ENTRY  gPlatformConsole[] = {
> >
> > +  {
> >
> > +    NULL,
> >
> > +    0
> >
> > +  }
> >
> > +};
> >
> > +
> >
> > +GLOBAL_REMOVE_IF_UNREFERENCED USB_CLASS_FORMAT_DEVICE_PATH
> > gUsbClassKeyboardDevicePath = {
> >
> > +  {
> >
> > +    {
> >
> > +      MESSAGING_DEVICE_PATH,
> >
> > +      MSG_USB_CLASS_DP,
> >
> > +      {
> >
> > +        (UINT8)(sizeof (USB_CLASS_DEVICE_PATH)),
> >
> > +        (UINT8)((sizeof (USB_CLASS_DEVICE_PATH)) >> 8)
> >
> > +      }
> >
> > +    },
> >
> > +    0xffff,           // VendorId
> >
> > +    0xffff,           // ProductId
> >
> > +    CLASS_HID,        // DeviceClass
> >
> > +    SUBCLASS_BOOT,    // DeviceSubClass
> >
> > +    PROTOCOL_KEYBOARD // DeviceProtocol
> >
> > +  },
> >
> > +  gEndEntire
> >
> > +};
> >
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/MdeModulePkg/Universal/
> > CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/MdeModulePkg/Universal/
> > CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
> >
> > new file mode 100644
> >
> > index 0000000000..c99dd4cd47
> >
> > --- /dev/null
> >
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/MdeModulePkg/Universal/
> > CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
> >
> > @@ -0,0 +1,122 @@
> >
> > +## @file
> >
> > +#  Capsule Runtime DXE Module INF file
> >
> > +#
> >
> > +# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
> >
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> >
> > +#
> >
> > +##
> >
> > +
> >
> > +## @file
> >
> > +#  Capsule Runtime Driver produces two UEFI capsule runtime services:
> > (UpdateCapsule, QueryCapsuleCapabilities).
> >
> > +#
> >
> > +#  It installs the Capsule Architectural Protocol defined in PI1.0a to signify
> >
> > +#  the capsule runtime services are ready.
> >
> > +#
> >
> > +#  Copyright (c) 2006 - 2020, Intel Corporation. All rights reserved.<BR>
> >
> > +#  Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights
> > reserved.<BR>
> >
> > +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> >
> > +#
> >
> > +##
> >
> > +
> >
> > +[Defines]
> >
> > +  INF_VERSION                    = 0x00010005
> >
> > +  BASE_NAME                      = CapsuleRuntimeDxe
> >
> > +  MODULE_UNI_FILE                = CapsuleRuntimeDxe.uni
> >
> > +  FILE_GUID                      = 42857F0A-13F2-4B21-8A23-53D3F714B840
> >
> > +  MODULE_TYPE                    = DXE_RUNTIME_DRIVER
> >
> > +  VERSION_STRING                 = 1.0
> >
> > +  ENTRY_POINT                    = CapsuleServiceInitialize
> >
> > +
> >
> > +#
> >
> > +# The following information is for reference only and not required by the
> build
> > tools.
> >
> > +#
> >
> > +#  VALID_ARCHITECTURES           = IA32 X64 EBC ARM AARCH64 RISCV64
> >
> > +#
> >
> > +
> >
> > +[Sources]
> >
> > +  CapsuleService.c
> >
> > +  CapsuleService.h
> >
> > +
> >
> > +[Sources.Ia32, Sources.EBC, Sources.ARM, Sources.AARCH64,
> > Sources.RISCV64]
> >
> > +  SaveLongModeContext.c
> >
> > +
> >
> > +[Sources.Ia32, Sources.X64, Sources.ARM, Sources.AARCH64,
> > Sources.RISCV64]
> >
> > +  CapsuleCache.c
> >
> > +
> >
> > +[Sources.Ia32, Sources.X64, Sources.EBC, Sources.RISCV64]
> >
> > +  CapsuleReset.c
> >
> > +
> >
> > +[Sources.ARM, Sources.AARCH64]
> >
> > +  Arm/CapsuleReset.c
> >
> > +
> >
> > +[Sources.EBC]
> >
> > +  CapsuleCacheNull.c
> >
> > +
> >
> > +[Sources.X64]
> >
> > +  X64/SaveLongModeContext.c
> >
> > +
> >
> > +[Packages]
> >
> > +  MdePkg/MdePkg.dec
> >
> > +  MdeModulePkg/MdeModulePkg.dec
> >
> > +  VanGoghCommonPkg/AmdCommonPkg.dec
> >
> > +
> >
> > +[LibraryClasses]
> >
> > +  UefiBootServicesTableLib
> >
> > +  PcdLib
> >
> > +  DebugLib
> >
> > +  UefiRuntimeServicesTableLib
> >
> > +  UefiDriverEntryPoint
> >
> > +  CapsuleLib
> >
> > +  UefiRuntimeLib
> >
> > +  BaseLib
> >
> > +  PrintLib
> >
> > +  BaseMemoryLib
> >
> > +  CacheMaintenanceLib
> >
> > +  IoLib
> >
> > +
> >
> > +[LibraryClasses.X64]
> >
> > +  UefiLib
> >
> > +  BaseMemoryLib
> >
> > +
> >
> > +[Guids]
> >
> > +  ## SOMETIMES_PRODUCES   ## Variable:L"CapsuleUpdateData" # (Process
> > across reset capsule image) for capsule updated data
> >
> > +  ## SOMETIMES_PRODUCES   ## Variable:L"CapsuleLongModeBuffer" # The
> > long mode buffer used by IA32 Capsule PEIM to call X64 CapsuleCoalesce
> code
> > to handle >4GB capsule blocks
> >
> > +  gEfiCapsuleVendorGuid
> >
> > +  gEfiFmpCapsuleGuid                            ## SOMETIMES_CONSUMES   ## GUID #
> > FMP capsule GUID
> >
> > +  gAmdSetCapsuleS3FlagGuid                      ## SOMETIMES_CONSUMES
> >
> > +  gEfiEventVirtualAddressChangeGuid             ## CONSUMES
> >
> > +
> >
> > +[Protocols]
> >
> > +  gEfiCapsuleArchProtocolGuid                   ## PRODUCES
> >
> > +  gEfiMmCommunication2ProtocolGuid              ## CONSUMES
> >
> > +
> >
> > +[Protocols.X64]
> >
> > +  ## UNDEFINED ## NOTIFY
> >
> > +  ## SOMETIMES_CONSUMES
> >
> > +  gEdkiiVariableLockProtocolGuid
> >
> > +
> >
> > +[FeaturePcd]
> >
> > +  gEfiMdeModulePkgTokenSpaceGuid.PcdSupportUpdateCapsuleReset
> ##
> > CONSUMES
> >
> > +
> gEfiMdeModulePkgTokenSpaceGuid.PcdSupportProcessCapsuleAtRuntime
> > ## CONSUMES
> >
> > +
> >
> > +[FeaturePcd.X64]
> >
> > +  gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode      ##
> > CONSUMES
> >
> > +
> >
> > +[Pcd]
> >
> > +  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxSizeNonPopulateCapsule   ##
> > SOMETIMES_CONSUMES
> >
> > +  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxSizePopulateCapsule      ##
> > SOMETIMES_CONSUMES # Populate Image requires reset support.
> >
> > +  gEfiMdeModulePkgTokenSpaceGuid.PcdCapsuleInRamSupport         ##
> > CONSUMES
> >
> > +
> >
> > +[Pcd.X64]
> >
> > +  gEfiMdeModulePkgTokenSpaceGuid.PcdCapsulePeiLongModeStackSize
> ##
> > SOMETIMES_CONSUMES
> >
> > +  gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable                ##
> > SOMETIMES_CONSUMES
> >
> > +
> >
> > +[Depex]
> >
> > +  gEfiVariableWriteArchProtocolGuid AND            # Depends on variable write
> > functionality to produce capsule data variable
> >
> > +  gEfiMmCommunication2ProtocolGuid                 # Perform AMD Specific
> flags
> > settings
> >
> > +
> >
> > +# [Hob.X64]
> >
> > +# UNDEFINED                 ## SOMETIMES_CONSUMES # CPU
> >
> > +
> >
> > +[UserExtensions.TianoCore."ExtraFiles"]
> >
> > +  CapsuleRuntimeDxeExtra.uni
> >
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/MdeModulePkg/Universal/
> > CapsuleRuntimeDxe/CapsuleService.c
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/MdeModulePkg/Universal/
> > CapsuleRuntimeDxe/CapsuleService.c
> >
> > new file mode 100644
> >
> > index 0000000000..45e9e40e2f
> >
> > --- /dev/null
> >
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/MdeModulePkg/Universal/
> > CapsuleRuntimeDxe/CapsuleService.c
> >
> > @@ -0,0 +1,470 @@
> >
> > +/** @file
> >
> > +  Implements CapsuleService.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
> >
> > +  Capsule Runtime Driver produces two UEFI capsule runtime services.
> >
> > +  (UpdateCapsule, QueryCapsuleCapabilities)
> >
> > +  It installs the Capsule Architectural Protocol defined in PI1.0a to signify
> >
> > +  the capsule runtime services are ready.
> >
> > +
> >
> > +Copyright (c) 2006 - 2020, Intel Corporation. All rights reserved.<BR>
> >
> > +SPDX-License-Identifier: BSD-2-Clause-Patent
> >
> > +
> >
> > +**/
> >
> > +
> >
> > +#include "CapsuleService.h"
> >
> > +
> >
> > +#include <Library/IoLib.h>
> >
> > +
> >
> > +//
> >
> > +// Handle for the installation of Capsule Architecture Protocol.
> >
> > +//
> >
> > +EFI_HANDLE  mNewHandle = NULL;
> >
> > +
> >
> > +//
> >
> > +// The times of calling UpdateCapsule ()
> >
> > +//
> >
> > +UINTN  mTimes = 0;
> >
> > +
> >
> > +UINT32  mMaxSizePopulateCapsule    = 0;
> >
> > +UINT32  mMaxSizeNonPopulateCapsule = 0;
> >
> > +
> >
> > +// Cached MM Communication protocol.
> >
> > +EFI_MM_COMMUNICATION2_PROTOCOL  *mMmCommunication2 =
> NULL;
> >
> > +
> >
> > +// For MM Communication purpose.
> >
> > +EFI_MM_COMMUNICATE_HEADER  *mCommunicationBuffer         = NULL;
> >
> > +EFI_MM_COMMUNICATE_HEADER  *mCommunicationBufferPhysical =
> > NULL;
> >
> > +EFI_EVENT                  mVirtualAddressChangeEvent    = NULL;
> >
> > +extern EFI_GUID            gAmdSetCapsuleS3FlagGuid;
> >
> > +
> >
> > +/**
> >
> > +  Passes capsules to the firmware with both virtual and physical mapping.
> > Depending on the intended
> >
> > +  consumption, the firmware may process the capsule immediately. If the
> > payload should persist
> >
> > +  across a system reset, the reset value returned from
> > EFI_QueryCapsuleCapabilities must
> >
> > +  be passed into ResetSystem() and will cause the capsule to be processed
> by
> > the firmware as
> >
> > +  part of the reset process.
> >
> > +
> >
> > +  @param  CapsuleHeaderArray    Virtual pointer to an array of virtual
> > pointers to the capsules
> >
> > +                                being passed into update capsule.
> >
> > +  @param  CapsuleCount          Number of pointers to EFI_CAPSULE_HEADER
> > in
> >
> > +                                CaspuleHeaderArray.
> >
> > +  @param  ScatterGatherList     Physical pointer to a set of
> >
> > +                                EFI_CAPSULE_BLOCK_DESCRIPTOR that describes the
> >
> > +                                location in physical memory of a set of capsules.
> >
> > +
> >
> > +  @retval EFI_SUCCESS           Valid capsule was passed. If
> >
> > +                                CAPSULE_FLAGS_PERSIT_ACROSS_RESET is not set, the
> >
> > +                                capsule has been successfully processed by the firmware.
> >
> > +  @retval EFI_DEVICE_ERROR      The capsule update was started, but failed
> > due to a device error.
> >
> > +  @retval EFI_INVALID_PARAMETER CapsuleSize is NULL, or an incompatible
> > set of flags were
> >
> > +                                set in the capsule header.
> >
> > +  @retval EFI_INVALID_PARAMETER CapsuleCount is Zero.
> >
> > +  @retval EFI_INVALID_PARAMETER For across reset capsule image,
> > ScatterGatherList is NULL.
> >
> > +  @retval EFI_UNSUPPORTED       CapsuleImage is not recognized by the
> > firmware.
> >
> > +  @retval EFI_OUT_OF_RESOURCES  When ExitBootServices() has been
> > previously called this error indicates the capsule
> >
> > +                                is compatible with this platform but is not capable of being
> > submitted or processed
> >
> > +                                in runtime. The caller may resubmit the capsule prior to
> > ExitBootServices().
> >
> > +  @retval EFI_OUT_OF_RESOURCES  When ExitBootServices() has not been
> > previously called then this error indicates
> >
> > +                                the capsule is compatible with this platform but there are
> > insufficient resources to process.
> >
> > +
> >
> > +**/
> >
> > +EFI_STATUS
> >
> > +EFIAPI
> >
> > +UpdateCapsule (
> >
> > +  IN EFI_CAPSULE_HEADER    **CapsuleHeaderArray,
> >
> > +  IN UINTN                 CapsuleCount,
> >
> > +  IN EFI_PHYSICAL_ADDRESS  ScatterGatherList OPTIONAL
> >
> > +  )
> >
> > +{
> >
> > +  UINTN               ArrayNumber;
> >
> > +  EFI_STATUS          Status;
> >
> > +  EFI_CAPSULE_HEADER  *CapsuleHeader;
> >
> > +  BOOLEAN             NeedReset;
> >
> > +  BOOLEAN             InitiateReset;
> >
> > +  CHAR16              CapsuleVarName[30];
> >
> > +  CHAR16              *TempVarName;
> >
> > +
> >
> > +  //
> >
> > +  // Check if platform support Capsule In RAM or not.
> >
> > +  // Platform could choose to drop CapsulePei/CapsuleX64 and do not
> > support Capsule In RAM.
> >
> > +  //
> >
> > +  if (!PcdGetBool (PcdCapsuleInRamSupport)) {
> >
> > +    return EFI_UNSUPPORTED;
> >
> > +  }
> >
> > +
> >
> > +  //
> >
> > +  // Capsule Count can't be less than one.
> >
> > +  //
> >
> > +  if (CapsuleCount < 1) {
> >
> > +    return EFI_INVALID_PARAMETER;
> >
> > +  }
> >
> > +
> >
> > +  NeedReset         = FALSE;
> >
> > +  InitiateReset     = FALSE;
> >
> > +  CapsuleHeader     = NULL;
> >
> > +  CapsuleVarName[0] = 0;
> >
> > +
> >
> > +  for (ArrayNumber = 0; ArrayNumber < CapsuleCount; ArrayNumber++) {
> >
> > +    //
> >
> > +    // A capsule which has the CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE
> > flag must have
> >
> > +    // CAPSULE_FLAGS_PERSIST_ACROSS_RESET set in its header as well.
> >
> > +    //
> >
> > +    CapsuleHeader = CapsuleHeaderArray[ArrayNumber];
> >
> > +    if ((CapsuleHeader->Flags & (CAPSULE_FLAGS_PERSIST_ACROSS_RESET |
> > CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE)) ==
> > CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) {
> >
> > +      return EFI_INVALID_PARAMETER;
> >
> > +    }
> >
> > +
> >
> > +    //
> >
> > +    // A capsule which has the CAPSULE_FLAGS_INITIATE_RESET flag must
> > have
> >
> > +    // CAPSULE_FLAGS_PERSIST_ACROSS_RESET set in its header as well.
> >
> > +    //
> >
> > +    if ((CapsuleHeader->Flags & (CAPSULE_FLAGS_PERSIST_ACROSS_RESET |
> > CAPSULE_FLAGS_INITIATE_RESET)) == CAPSULE_FLAGS_INITIATE_RESET) {
> >
> > +      return EFI_INVALID_PARAMETER;
> >
> > +    }
> >
> > +
> >
> > +    //
> >
> > +    // Check FMP capsule flag
> >
> > +    //
> >
> > +    if (  CompareGuid (&CapsuleHeader->CapsuleGuid,
> &gEfiFmpCapsuleGuid)
> >
> > +       && ((CapsuleHeader->Flags &
> > CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) != 0))
> >
> > +    {
> >
> > +      return EFI_INVALID_PARAMETER;
> >
> > +    }
> >
> > +
> >
> > +    //
> >
> > +    // Check Capsule image without populate flag by firmware support
> capsule
> > function
> >
> > +    //
> >
> > +    if ((CapsuleHeader->Flags &
> CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE)
> > == 0) {
> >
> > +      Status = SupportCapsuleImage (CapsuleHeader);
> >
> > +      if (EFI_ERROR (Status)) {
> >
> > +        return Status;
> >
> > +      }
> >
> > +    }
> >
> > +  }
> >
> > +
> >
> > +  //
> >
> > +  // Walk through all capsules, record whether there is a capsule needs reset
> >
> > +  // or initiate reset. And then process capsules which has no reset flag
> > directly.
> >
> > +  //
> >
> > +  for (ArrayNumber = 0; ArrayNumber < CapsuleCount; ArrayNumber++) {
> >
> > +    CapsuleHeader = CapsuleHeaderArray[ArrayNumber];
> >
> > +    //
> >
> > +    // Here should be in the boot-time for non-reset capsule image
> >
> > +    // Platform specific update for the non-reset capsule image.
> >
> > +    //
> >
> > +    if ((CapsuleHeader->Flags & CAPSULE_FLAGS_PERSIST_ACROSS_RESET)
> ==
> > 0) {
> >
> > +      if (EfiAtRuntime () && !FeaturePcdGet
> > (PcdSupportProcessCapsuleAtRuntime)) {
> >
> > +        Status = EFI_OUT_OF_RESOURCES;
> >
> > +      } else {
> >
> > +        Status = ProcessCapsuleImage (CapsuleHeader);
> >
> > +      }
> >
> > +
> >
> > +      if (EFI_ERROR (Status)) {
> >
> > +        return Status;
> >
> > +      }
> >
> > +    } else {
> >
> > +      NeedReset = TRUE;
> >
> > +      if ((CapsuleHeader->Flags & CAPSULE_FLAGS_INITIATE_RESET) != 0) {
> >
> > +        InitiateReset = TRUE;
> >
> > +      }
> >
> > +    }
> >
> > +  }
> >
> > +
> >
> > +  //
> >
> > +  // After launching all capsules who has no reset flag, if no more capsules
> > claims
> >
> > +  // for a system reset just return.
> >
> > +  //
> >
> > +  if (!NeedReset) {
> >
> > +    return EFI_SUCCESS;
> >
> > +  }
> >
> > +
> >
> > +  //
> >
> > +  // ScatterGatherList is only referenced if the capsules are defined to persist
> > across
> >
> > +  // system reset.
> >
> > +  //
> >
> > +  if (ScatterGatherList == (EFI_PHYSICAL_ADDRESS)(UINTN)NULL) {
> >
> > +    return EFI_INVALID_PARAMETER;
> >
> > +  }
> >
> > +
> >
> > +  //
> >
> > +  // Check if the platform supports update capsule across a system reset
> >
> > +  //
> >
> > +  if (!IsPersistAcrossResetCapsuleSupported ()) {
> >
> > +    return EFI_UNSUPPORTED;
> >
> > +  }
> >
> > +
> >
> > +  CapsuleCacheWriteBack (ScatterGatherList);
> >
> > +
> >
> > +  //
> >
> > +  // Construct variable name CapsuleUpdateData, CapsuleUpdateData1,
> > CapsuleUpdateData2...
> >
> > +  // if user calls UpdateCapsule multiple times.
> >
> > +  //
> >
> > +  StrCpyS (CapsuleVarName, sizeof (CapsuleVarName)/sizeof (CHAR16),
> > EFI_CAPSULE_VARIABLE_NAME);
> >
> > +  TempVarName = CapsuleVarName + StrLen (CapsuleVarName);
> >
> > +  if (mTimes > 0) {
> >
> > +    UnicodeValueToStringS (
> >
> > +      TempVarName,
> >
> > +      sizeof (CapsuleVarName) - ((UINTN)TempVarName -
> > (UINTN)CapsuleVarName),
> >
> > +      0,
> >
> > +      mTimes,
> >
> > +      0
> >
> > +      );
> >
> > +  }
> >
> > +
> >
> > +  //
> >
> > +  // ScatterGatherList is only referenced if the capsules are defined to persist
> > across
> >
> > +  // system reset. Set its value into NV storage to let pre-boot driver to pick
> it
> > up
> >
> > +  // after coming through a system reset.
> >
> > +  //
> >
> > +  Status = EfiSetVariable (
> >
> > +             CapsuleVarName,
> >
> > +             &gEfiCapsuleVendorGuid,
> >
> > +             EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS |
> > EFI_VARIABLE_BOOTSERVICE_ACCESS,
> >
> > +             sizeof (UINTN),
> >
> > +             (VOID *)&ScatterGatherList
> >
> > +             );
> >
> > +  if (!EFI_ERROR (Status)) {
> >
> > +    //
> >
> > +    // Variable has been set successfully, increase variable index.
> >
> > +    //
> >
> > +    mTimes++;
> >
> > +    if (InitiateReset) {
> >
> > +      //
> >
> > +      // Firmware that encounters a capsule which has the
> > CAPSULE_FLAGS_INITIATE_RESET Flag set in its header
> >
> > +      // will initiate a reset of the platform which is compatible with the
> passed-
> > in capsule request and will
> >
> > +      // not return back to the caller.
> >
> > +      //
> >
> > +      // EfiResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);
> >
> > +      // Invoke AMD Specific S3.
> >
> > +      DEBUG ((DEBUG_INFO, "Setting AMD Specific S3 Flag.\n"));
> >
> > +      Status = mMmCommunication2->Communicate (
> >
> > +                                    mMmCommunication2,
> >
> > +                                    mCommunicationBufferPhysical,
> >
> > +                                    mCommunicationBuffer,
> >
> > +                                    NULL
> >
> > +                                    );
> >
> > +    }
> >
> > +  }
> >
> > +
> >
> > +  return Status;
> >
> > +}
> >
> > +
> >
> > +/**
> >
> > +  Returns if the capsule can be supported via UpdateCapsule().
> >
> > +  Notice: When PcdCapsuleInRamSupport is unsupported, even this routine
> > returns a valid answer,
> >
> > +  the capsule still is unsupported via UpdateCapsule().
> >
> > +
> >
> > +  @param  CapsuleHeaderArray    Virtual pointer to an array of virtual
> > pointers to the capsules
> >
> > +                                being passed into update capsule.
> >
> > +  @param  CapsuleCount          Number of pointers to EFI_CAPSULE_HEADER
> > in
> >
> > +                                CaspuleHeaderArray.
> >
> > +  @param  MaxiumCapsuleSize     On output the maximum size that
> > UpdateCapsule() can
> >
> > +                                support as an argument to UpdateCapsule() via
> >
> > +                                CapsuleHeaderArray and ScatterGatherList.
> >
> > +  @param  ResetType             Returns the type of reset required for the
> capsule
> > update.
> >
> > +
> >
> > +  @retval EFI_SUCCESS           Valid answer returned.
> >
> > +  @retval EFI_UNSUPPORTED       The capsule image is not supported on this
> > platform, and
> >
> > +                                MaximumCapsuleSize and ResetType are undefined.
> >
> > +  @retval EFI_INVALID_PARAMETER MaximumCapsuleSize is NULL, or
> > ResetTyep is NULL,
> >
> > +                                Or CapsuleCount is Zero, or CapsuleImage is not valid.
> >
> > +
> >
> > +**/
> >
> > +EFI_STATUS
> >
> > +EFIAPI
> >
> > +QueryCapsuleCapabilities (
> >
> > +  IN  EFI_CAPSULE_HEADER  **CapsuleHeaderArray,
> >
> > +  IN  UINTN               CapsuleCount,
> >
> > +  OUT UINT64              *MaxiumCapsuleSize,
> >
> > +  OUT EFI_RESET_TYPE      *ResetType
> >
> > +  )
> >
> > +{
> >
> > +  EFI_STATUS          Status;
> >
> > +  UINTN               ArrayNumber;
> >
> > +  EFI_CAPSULE_HEADER  *CapsuleHeader;
> >
> > +  BOOLEAN             NeedReset;
> >
> > +
> >
> > +  //
> >
> > +  // Capsule Count can't be less than one.
> >
> > +  //
> >
> > +  if (CapsuleCount < 1) {
> >
> > +    return EFI_INVALID_PARAMETER;
> >
> > +  }
> >
> > +
> >
> > +  //
> >
> > +  // Check whether input parameter is valid
> >
> > +  //
> >
> > +  if ((MaxiumCapsuleSize == NULL) || (ResetType == NULL)) {
> >
> > +    return EFI_INVALID_PARAMETER;
> >
> > +  }
> >
> > +
> >
> > +  CapsuleHeader = NULL;
> >
> > +  NeedReset     = FALSE;
> >
> > +
> >
> > +  for (ArrayNumber = 0; ArrayNumber < CapsuleCount; ArrayNumber++) {
> >
> > +    CapsuleHeader = CapsuleHeaderArray[ArrayNumber];
> >
> > +    //
> >
> > +    // A capsule which has the CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE
> > flag must have
> >
> > +    // CAPSULE_FLAGS_PERSIST_ACROSS_RESET set in its header as well.
> >
> > +    //
> >
> > +    if ((CapsuleHeader->Flags & (CAPSULE_FLAGS_PERSIST_ACROSS_RESET |
> > CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE)) ==
> > CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) {
> >
> > +      return EFI_INVALID_PARAMETER;
> >
> > +    }
> >
> > +
> >
> > +    //
> >
> > +    // A capsule which has the CAPSULE_FLAGS_INITIATE_RESET flag must
> > have
> >
> > +    // CAPSULE_FLAGS_PERSIST_ACROSS_RESET set in its header as well.
> >
> > +    //
> >
> > +    if ((CapsuleHeader->Flags & (CAPSULE_FLAGS_PERSIST_ACROSS_RESET |
> > CAPSULE_FLAGS_INITIATE_RESET)) == CAPSULE_FLAGS_INITIATE_RESET) {
> >
> > +      return EFI_INVALID_PARAMETER;
> >
> > +    }
> >
> > +
> >
> > +    //
> >
> > +    // Check FMP capsule flag
> >
> > +    //
> >
> > +    if (  CompareGuid (&CapsuleHeader->CapsuleGuid,
> &gEfiFmpCapsuleGuid)
> >
> > +       && ((CapsuleHeader->Flags &
> > CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) != 0))
> >
> > +    {
> >
> > +      return EFI_INVALID_PARAMETER;
> >
> > +    }
> >
> > +
> >
> > +    //
> >
> > +    // Check Capsule image without populate flag is supported by firmware
> >
> > +    //
> >
> > +    if ((CapsuleHeader->Flags &
> CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE)
> > == 0) {
> >
> > +      Status = SupportCapsuleImage (CapsuleHeader);
> >
> > +      if (EFI_ERROR (Status)) {
> >
> > +        return Status;
> >
> > +      }
> >
> > +    }
> >
> > +  }
> >
> > +
> >
> > +  //
> >
> > +  // Find out whether there is any capsule defined to persist across system
> > reset.
> >
> > +  //
> >
> > +  for (ArrayNumber = 0; ArrayNumber < CapsuleCount; ArrayNumber++) {
> >
> > +    CapsuleHeader = CapsuleHeaderArray[ArrayNumber];
> >
> > +    if ((CapsuleHeader->Flags &
> CAPSULE_FLAGS_PERSIST_ACROSS_RESET) !=
> > 0) {
> >
> > +      NeedReset = TRUE;
> >
> > +      break;
> >
> > +    }
> >
> > +  }
> >
> > +
> >
> > +  if (NeedReset) {
> >
> > +    //
> >
> > +    // Check if the platform supports update capsule across a system reset
> >
> > +    //
> >
> > +    if (!IsPersistAcrossResetCapsuleSupported ()) {
> >
> > +      return EFI_UNSUPPORTED;
> >
> > +    }
> >
> > +
> >
> > +    *ResetType         = EfiResetWarm;
> >
> > +    *MaxiumCapsuleSize = (UINT64)mMaxSizePopulateCapsule;
> >
> > +  } else {
> >
> > +    //
> >
> > +    // For non-reset capsule image.
> >
> > +    //
> >
> > +    *ResetType         = EfiResetCold;
> >
> > +    *MaxiumCapsuleSize = (UINT64)mMaxSizeNonPopulateCapsule;
> >
> > +  }
> >
> > +
> >
> > +  return EFI_SUCCESS;
> >
> > +}
> >
> > +
> >
> > +/**
> >
> > +  Notification function of EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE.
> >
> > +
> >
> > +  Here it converts the SMM Communicate buffer address into virtual.
> >
> > +
> >
> > +  @param[in]  Event        Event whose notification function is being invoked.
> >
> > +  @param[in]  Context      Pointer to the notification function's context.
> >
> > +
> >
> > +**/
> >
> > +VOID
> >
> > +EFIAPI
> >
> > +VariableAddressChangeEvent (
> >
> > +  IN EFI_EVENT  Event,
> >
> > +  IN VOID       *Context
> >
> > +  )
> >
> > +{
> >
> > +  EfiConvertPointer (0x0, (VOID **)&mCommunicationBuffer);
> >
> > +  EfiConvertPointer (0x0, (VOID **)&mMmCommunication2);
> >
> > +}
> >
> > +
> >
> > +/**
> >
> > +
> >
> > +  This code installs UEFI capsule runtime service.
> >
> > +
> >
> > +  @param  ImageHandle    The firmware allocated handle for the EFI image.
> >
> > +  @param  SystemTable    A pointer to the EFI System Table.
> >
> > +
> >
> > +  @retval EFI_SUCCESS    UEFI Capsule Runtime Services are installed
> > successfully.
> >
> > +
> >
> > +**/
> >
> > +EFI_STATUS
> >
> > +EFIAPI
> >
> > +CapsuleServiceInitialize (
> >
> > +  IN EFI_HANDLE        ImageHandle,
> >
> > +  IN EFI_SYSTEM_TABLE  *SystemTable
> >
> > +  )
> >
> > +{
> >
> > +  EFI_STATUS  Status;
> >
> > +
> >
> > +  mMaxSizePopulateCapsule    = PcdGet32 (PcdMaxSizePopulateCapsule);
> >
> > +  mMaxSizeNonPopulateCapsule = PcdGet32
> > (PcdMaxSizeNonPopulateCapsule);
> >
> > +
> >
> > +  //
> >
> > +  // When PEI phase is IA32, DXE phase is X64, it is possible that capsule
> data
> > are
> >
> > +  // put above 4GB, so capsule PEI will transfer to long mode to get capsule
> > data.
> >
> > +  // The page table and stack is used to transfer processor mode from IA32
> to
> > long mode.
> >
> > +  // Create the base address of page table and stack, and save them into
> > variable.
> >
> > +  // This is not needed when capsule with reset type is not supported.
> >
> > +  //
> >
> > +  SaveLongModeContext ();
> >
> > +
> >
> > +  //
> >
> > +  // Install capsule runtime services into UEFI runtime service tables.
> >
> > +  //
> >
> > +  gRT->UpdateCapsule            = UpdateCapsule;
> >
> > +  gRT->QueryCapsuleCapabilities = QueryCapsuleCapabilities;
> >
> > +
> >
> > +  //
> >
> > +  // Install the Capsule Architectural Protocol on a new handle
> >
> > +  // to signify the capsule runtime services are ready.
> >
> > +  //
> >
> > +  Status = gBS->InstallMultipleProtocolInterfaces (
> >
> > +                  &mNewHandle,
> >
> > +                  &gEfiCapsuleArchProtocolGuid,
> >
> > +                  NULL,
> >
> > +                  NULL
> >
> > +                  );
> >
> > +  ASSERT_EFI_ERROR (Status);
> >
> > +
> >
> > +  Status = gBS->LocateProtocol (&gEfiMmCommunication2ProtocolGuid,
> > NULL, (VOID **)&mMmCommunication2);
> >
> > +  ASSERT_EFI_ERROR (Status);
> >
> > +  Status = gBS->AllocatePool (EfiRuntimeServicesData, sizeof
> > (EFI_MM_COMMUNICATE_HEADER), (VOID
> > **)&mCommunicationBufferPhysical);
> >
> > +  ASSERT_EFI_ERROR (Status);
> >
> > +  CopyGuid (&(mCommunicationBufferPhysical->HeaderGuid),
> > &gAmdSetCapsuleS3FlagGuid);
> >
> > +  mCommunicationBufferPhysical->MessageLength = 0;
> >
> > +  mCommunicationBuffer                        = mCommunicationBufferPhysical;
> >
> > +
> >
> > +  // Create an event to update SMM pointers.
> >
> > +  gBS->CreateEventEx (
> >
> > +         EVT_NOTIFY_SIGNAL,
> >
> > +         TPL_NOTIFY,
> >
> > +         VariableAddressChangeEvent,
> >
> > +         NULL,
> >
> > +         &gEfiEventVirtualAddressChangeGuid,
> >
> > +         &mVirtualAddressChangeEvent
> >
> > +         );
> >
> > +
> >
> > +  return Status;
> >
> > +}
> >
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/MdeModulePkg/Universal/
> > CapsuleRuntimeDxe/CapsuleService.h
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/MdeModulePkg/Universal/
> > CapsuleRuntimeDxe/CapsuleService.h
> >
> > new file mode 100644
> >
> > index 0000000000..d5df075e46
> >
> > --- /dev/null
> >
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/MdeModulePkg/Universal/
> > CapsuleRuntimeDxe/CapsuleService.h
> >
> > @@ -0,0 +1,82 @@
> >
> > +/** @file
> >
> > +  Implements CapsuleService.h
> >
> > +
> >
> > +  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
> >
> > +  Capsule Runtime Driver produces two UEFI capsule runtime services.
> >
> > +  (UpdateCapsule, QueryCapsuleCapabilities)
> >
> > +  It installs the Capsule Architectural Protocol defined in PI1.0a to signify
> >
> > +  the capsule runtime services are ready.
> >
> > +
> >
> > +  Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
> >
> > +  Copyright (c) 2018, Linaro, Ltd. All rights reserved.<BR>
> >
> > +
> >
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> >
> > +
> >
> > +**/
> >
> > +
> >
> > +#ifndef _CAPSULE_SERVICE_H_
> >
> > +#define _CAPSULE_SERVICE_H_
> >
> > +
> >
> > +#include <Uefi.h>
> >
> > +
> >
> > +#include <Protocol/Capsule.h>
> >
> > +#include <Protocol/MmCommunication2.h>
> >
> > +#include <Guid/CapsuleVendor.h>
> >
> > +#include <Guid/FmpCapsule.h>
> >
> > +#include <Guid/EventGroup.h>
> >
> > +
> >
> > +#include <Library/DebugLib.h>
> >
> > +#include <Library/PcdLib.h>
> >
> > +#include <Library/CapsuleLib.h>
> >
> > +#include <Library/UefiDriverEntryPoint.h>
> >
> > +#include <Library/UefiBootServicesTableLib.h>
> >
> > +#include <Library/UefiRuntimeServicesTableLib.h>
> >
> > +#include <Library/UefiRuntimeLib.h>
> >
> > +#include <Library/BaseLib.h>
> >
> > +#include <Library/PrintLib.h>
> >
> > +#include <Library/BaseMemoryLib.h>
> >
> > +
> >
> > +/**
> >
> > +  Create the variable to save the base address of page table and stack
> >
> > +  for transferring into long mode in IA32 PEI.
> >
> > +**/
> >
> > +VOID
> >
> > +SaveLongModeContext (
> >
> > +  VOID
> >
> > +  );
> >
> > +
> >
> > +/**
> >
> > +  Whether the platform supports capsules that persist across reset. Note
> that
> >
> > +  some platforms only support such capsules at boot time.
> >
> > +
> >
> > +  @return TRUE  if a PersistAcrossReset capsule may be passed to
> > UpdateCapsule()
> >
> > +                at this time
> >
> > +          FALSE otherwise
> >
> > +**/
> >
> > +BOOLEAN
> >
> > +IsPersistAcrossResetCapsuleSupported (
> >
> > +  VOID
> >
> > +  );
> >
> > +
> >
> > +/**
> >
> > +  Writes Back a range of data cache lines covering a set of capsules in
> memory.
> >
> > +
> >
> > +  Writes Back the data cache lines specified by ScatterGatherList.
> >
> > +
> >
> > +  @param  ScatterGatherList Physical address of the data structure that
> >
> > +                            describes a set of capsules in memory
> >
> > +
> >
> > +**/
> >
> > +VOID
> >
> > +CapsuleCacheWriteBack (
> >
> > +  IN  EFI_PHYSICAL_ADDRESS  ScatterGatherList
> >
> > +  );
> >
> > +
> >
> > +#endif
> >
> > --
> >
> > 2.31.1
> >
> >
>
>



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#114389): https://edk2.groups.io/g/devel/message/114389
Mute This Topic: https://groups.io/mt/103831164/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



  reply	other threads:[~2024-01-25 11:45 UTC|newest]

Thread overview: 49+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-01-18  6:50 [edk2-devel] [PATCH 00/33] Introduce AMD Vangogh platform reference code duke.zhai via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 01/33] AMD/AmdPlatformPkg: Check in AMD S3 logo duke.zhai via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 02/33] AMD/VanGoghBoard: Check in ACPI tables duke.zhai via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 03/33] AMD/VanGoghBoard: Check in Capsule update duke.zhai via groups.io
2024-01-23  4:42   ` Chang, Abner via groups.io
2024-01-25  8:25     ` Zhai, MingXin (Duke) via groups.io
2024-01-25 11:45       ` Chang, Abner via groups.io [this message]
2024-01-18  6:50 ` [edk2-devel] [PATCH 04/33] AMD/VanGoghBoard: Check in AgesaPublic pkg duke.zhai via groups.io
2024-01-23  4:44   ` Chang, Abner via groups.io
2024-01-25  8:17     ` Xing, Eric via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 05/33] AMD/VanGoghBoard: Check in PlatformSecLib duke.zhai via groups.io
2024-01-23  4:46   ` Chang, Abner via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 06/33] AMD/VanGoghBoard: Check in AmdIdsExtLib duke.zhai via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 07/33] AMD/VanGoghBoard: Check in PciPlatform duke.zhai via groups.io
2024-01-23  4:50   ` Chang, Abner via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 08/33] AMD/VanGoghBoard: Check in UDKFlashUpdate duke.zhai via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 09/33] AMD/VanGoghBoard: Check in Flash_AB duke.zhai via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 10/33] AMD/VanGoghBoard: Check in FlashUpdate duke.zhai via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 11/33] AMD/VanGoghBoard: Check in FvbServices duke.zhai via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 12/33] AMD/VanGoghBoard: Check in AMD BaseSerialPortLib duke.zhai via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 13/33] AMD/VanGoghBoard: Check in PlatformFlashAccessLib duke.zhai via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 14/33] AMD/VanGoghBoard: Check in SmbiosLib duke.zhai via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 15/33] AMD/VanGoghBoard: Check in SpiFlashDeviceLib duke.zhai via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 16/33] AMD/VanGoghBoard: Check in BaseTscTimerLib duke.zhai via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 17/33] AMD/VanGoghBoard: Check in Smm access module duke.zhai via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 18/33] AMD/VanGoghBoard: Check in PciHostBridge module duke.zhai via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 19/33] AMD/VanGoghBoard: Check in PcatRealTimeClockRuntimeDxe module duke.zhai via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 20/33] AMD/VanGoghBoard: Check in FTPM module duke.zhai via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 21/33] AMD/VanGoghBoard: Check in SignedCapsule duke.zhai via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 22/33] AMD/VanGoghBoard: Check in Vtf0 duke.zhai via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 23/33] AMD/VanGoghBoard: Check in AcpiPlatform duke.zhai via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 24/33] AMD/VanGoghBoard: Check in FchSpi module duke.zhai via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 25/33] AMD/VanGoghBoard: Check in PlatformInitPei module duke.zhai via groups.io
2024-01-23  6:35   ` Chang, Abner via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 26/33] AMD/VanGoghBoard: Check in Smbios platform dxe drivers duke.zhai via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 27/33] AMD/VanGoghBoard: Check in Fsp2WrapperPkg duke.zhai via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 28/33] AMD/VanGoghBoard: Check in SmmCpuFeaturesLibCommon module duke.zhai via groups.io
2024-01-23  5:14   ` Chang, Abner via groups.io
2024-01-23 10:20     ` Xing, Eric via groups.io
2024-01-23 10:44       ` Chang, Abner via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 29/33] AMD/VanGoghBoard: Check in SmramSaveState module duke.zhai via groups.io
2024-01-20 14:37   ` Abdul Lateef Attar via groups.io
2024-01-23  5:15     ` Chang, Abner via groups.io
2024-01-23 10:27       ` Xing, Eric via groups.io
2024-01-23 10:44         ` Chang, Abner via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 30/33] AMD/VanGoghBoard: Check in EDK2 override files duke.zhai via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 31/33] AMD/VanGoghBoard: Check in AMD SmmControlPei module duke.zhai via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 32/33] AMD/VanGoghBoard: Check in Chachani board project files and build script duke.zhai via groups.io
2024-01-18  6:50 ` [edk2-devel] [PATCH 33/33] AMD/VanGoghBoard: Improvement coding style duke.zhai via groups.io

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=LV8PR12MB9452EC9EF68A8B520A6E55DAEA7A2@LV8PR12MB9452.namprd12.prod.outlook.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox