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]
-=-=-=-=-=-=-=-=-=-=-=-
next prev parent 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