public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [edk2-devel] [PATCH 0/5] AmdMinBoardPkg: AMD board specific modules
@ 2024-05-17  3:49 Abdul Lateef Attar via groups.io
  2024-05-17  3:49 ` [edk2-devel] [PATCH 1/5] AmdMinBoardPkg: Uncrustify PciHotPlug module Abdul Lateef Attar via groups.io
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Abdul Lateef Attar via groups.io @ 2024-05-17  3:49 UTC (permalink / raw)
  To: devel; +Cc: Abdul Lateef Attar, Abner Chang, Paul Grimes

PR: https://github.com/tianocore/edk2-platforms/pull/143
Adds various module common to AMD boards.
Cc: Abner Chang <abner.chang@amd.com>
Cc: Paul Grimes <paul.grimes@amd.com>

Abdul Lateef Attar (5):
  AmdMinBoardPkg: Uncrustify PciHotPlug module
  AmdMinBoardPkg/Library: Uncrustify the Library module
  AmdMinBoardPkg: Implement BoardInitLib for PEI phase
  AmdMinBoardPkg: Implement BoardInitLib for DXE phase
  AmdMinBoardPkg: Implements BoardBdsHookLib library

 .../AMD/AmdMinBoardPkg/AmdMinBoardPkg.dec     |   10 +
 .../AMD/AmdMinBoardPkg/AmdMinBoardPkg.dsc     |   10 +-
 .../Include/Library/AmdBoardBdsHookLib.h      |  130 ++
 .../Library/BoardBdsHookLib/BoardBdsHook.h    |  242 +++
 .../Library/BoardBdsHookLib/BoardBdsHookLib.c | 1712 +++++++++++++++++
 .../BoardBdsHookLib/BoardBdsHookLib.inf       |  105 +
 .../Library/BoardBdsHookLib/BoardBootOption.c |  754 ++++++++
 .../Library/BoardBdsHookLib/BoardMemoryTest.c |   83 +
 .../Library/DxeBoardInitLib/DxeBoardInitLib.c |  253 +++
 .../DxeBoardInitLib/DxeBoardInitLib.inf       |   51 +
 .../DxeBoardInitLib/DxeBoardInitLibInternal.c |  306 +++
 .../DxeBoardInitLib/DxeBoardInitLibInternal.h |  159 ++
 .../DxeBoardInitLib/MadtAcpiTablePatch.c      |  243 +++
 .../PeiBoardInitPreMemLib/AmdMemoryInfoHob.h  |   50 +
 .../PeiBoardInitPreMemLib.c                   |  229 +++
 .../PeiBoardInitPreMemLib.inf                 |   45 +
 .../PeiBoardInitPreMemLib/PeiMemoryInit.c     |  198 ++
 .../PeiBoardInitPreMemLib/PeiMemoryInit.h     |   50 +
 .../Library/PeiReportFvLib/PeiReportFvLib.c   |   12 +-
 .../Library/SetCacheMtrrLib/SetCacheMtrrLib.c |    3 +-
 .../PciHotPlug/PciHotPlugInit.c               |    4 +-
 .../PciHotPlug/PciHotPlugInit.inf             |    5 +-
 22 files changed, 4647 insertions(+), 7 deletions(-)
 create mode 100644 Platform/AMD/AmdMinBoardPkg/Include/Library/AmdBoardBdsHookLib.h
 create mode 100644 Platform/AMD/AmdMinBoardPkg/Library/BoardBdsHookLib/BoardBdsHook.h
 create mode 100644 Platform/AMD/AmdMinBoardPkg/Library/BoardBdsHookLib/BoardBdsHookLib.c
 create mode 100644 Platform/AMD/AmdMinBoardPkg/Library/BoardBdsHookLib/BoardBdsHookLib.inf
 create mode 100644 Platform/AMD/AmdMinBoardPkg/Library/BoardBdsHookLib/BoardBootOption.c
 create mode 100644 Platform/AMD/AmdMinBoardPkg/Library/BoardBdsHookLib/BoardMemoryTest.c
 create mode 100644 Platform/AMD/AmdMinBoardPkg/Library/DxeBoardInitLib/DxeBoardInitLib.c
 create mode 100644 Platform/AMD/AmdMinBoardPkg/Library/DxeBoardInitLib/DxeBoardInitLib.inf
 create mode 100644 Platform/AMD/AmdMinBoardPkg/Library/DxeBoardInitLib/DxeBoardInitLibInternal.c
 create mode 100644 Platform/AMD/AmdMinBoardPkg/Library/DxeBoardInitLib/DxeBoardInitLibInternal.h
 create mode 100644 Platform/AMD/AmdMinBoardPkg/Library/DxeBoardInitLib/MadtAcpiTablePatch.c
 create mode 100644 Platform/AMD/AmdMinBoardPkg/Library/PeiBoardInitPreMemLib/AmdMemoryInfoHob.h
 create mode 100644 Platform/AMD/AmdMinBoardPkg/Library/PeiBoardInitPreMemLib/PeiBoardInitPreMemLib.c
 create mode 100644 Platform/AMD/AmdMinBoardPkg/Library/PeiBoardInitPreMemLib/PeiBoardInitPreMemLib.inf
 create mode 100644 Platform/AMD/AmdMinBoardPkg/Library/PeiBoardInitPreMemLib/PeiMemoryInit.c
 create mode 100644 Platform/AMD/AmdMinBoardPkg/Library/PeiBoardInitPreMemLib/PeiMemoryInit.h

-- 
2.34.1



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



^ permalink raw reply	[flat|nested] 7+ messages in thread

* [edk2-devel] [PATCH 1/5] AmdMinBoardPkg: Uncrustify PciHotPlug module
  2024-05-17  3:49 [edk2-devel] [PATCH 0/5] AmdMinBoardPkg: AMD board specific modules Abdul Lateef Attar via groups.io
@ 2024-05-17  3:49 ` Abdul Lateef Attar via groups.io
  2024-05-17  3:49 ` [edk2-devel] [PATCH 2/5] AmdMinBoardPkg/Library: Uncrustify the Library module Abdul Lateef Attar via groups.io
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Abdul Lateef Attar via groups.io @ 2024-05-17  3:49 UTC (permalink / raw)
  To: devel; +Cc: Abdul Lateef Attar, Abner Chang, Paul Grimes

Uncrustify PciHotPlug module.
corrects the [in, out] parameters.

Cc: Abner Chang <abner.chang@amd.com>
Cc: Paul Grimes <paul.grimes@amd.com>
Signed-off-by: Abdul Lateef Attar <AbdulLateef.Attar@amd.com>
---
 Platform/AMD/AmdMinBoardPkg/PciHotPlug/PciHotPlugInit.c   | 4 +++-
 Platform/AMD/AmdMinBoardPkg/PciHotPlug/PciHotPlugInit.inf | 5 +++--
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/Platform/AMD/AmdMinBoardPkg/PciHotPlug/PciHotPlugInit.c b/Platform/AMD/AmdMinBoardPkg/PciHotPlug/PciHotPlugInit.c
index a26ca16741..9a7b509b55 100755
--- a/Platform/AMD/AmdMinBoardPkg/PciHotPlug/PciHotPlugInit.c
+++ b/Platform/AMD/AmdMinBoardPkg/PciHotPlug/PciHotPlugInit.c
@@ -44,6 +44,8 @@
 
   Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
   Copyright (C) 2016, Red Hat, Inc.<BR>
+  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
+
   SPDX-License-Identifier: BSD-2-Clause-Patent
 
   @par Revision Reference:
@@ -169,7 +171,7 @@ InitializeRootHpc (
   @param[in]  This            Pointer to the EFI_PCI_HOT_PLUG_INIT_PROTOCOL instance.
   @param[in]  HpcDevicePath   The device path to the HPC.
   @param[in]  HpcPciAddress   The address of the HPC function on the PCI bus.
-  @param[in]  HpcState        The state of the HPC hardware.
+  @param[out] HpcState        The state of the HPC hardware.
   @param[out] Padding         The amount of resource padding that is required by the
                               PCI bus under the control of the specified HPC.
   @param[out] Attributes      Describes how padding is accounted for. The padding
diff --git a/Platform/AMD/AmdMinBoardPkg/PciHotPlug/PciHotPlugInit.inf b/Platform/AMD/AmdMinBoardPkg/PciHotPlug/PciHotPlugInit.inf
index 44564df387..861fc120d9 100755
--- a/Platform/AMD/AmdMinBoardPkg/PciHotPlug/PciHotPlugInit.inf
+++ b/Platform/AMD/AmdMinBoardPkg/PciHotPlug/PciHotPlugInit.inf
@@ -2,8 +2,9 @@
 # This driver implements EFI_PCI_HOT_PLUG_INIT_PROTOCOL.
 # Adds resource padding information, for PCIe hotplug purposes.
 #
-# Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved
-# SPDX-License-Identifier: BSD-2-Clause-Patent ##
+# Copyright (C) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserved
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
 
 [Defines]
   INF_VERSION                    = 1.29
-- 
2.34.1



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



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [edk2-devel] [PATCH 2/5] AmdMinBoardPkg/Library: Uncrustify the Library module
  2024-05-17  3:49 [edk2-devel] [PATCH 0/5] AmdMinBoardPkg: AMD board specific modules Abdul Lateef Attar via groups.io
  2024-05-17  3:49 ` [edk2-devel] [PATCH 1/5] AmdMinBoardPkg: Uncrustify PciHotPlug module Abdul Lateef Attar via groups.io
@ 2024-05-17  3:49 ` Abdul Lateef Attar via groups.io
  2024-05-17  3:49 ` [edk2-devel] [PATCH 3/5] AmdMinBoardPkg: Implement BoardInitLib for PEI phase Abdul Lateef Attar via groups.io
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Abdul Lateef Attar via groups.io @ 2024-05-17  3:49 UTC (permalink / raw)
  To: devel; +Cc: Abdul Lateef Attar, Abner Chang, Paul Grimes

Uncrustify the library module.
Update the function header.

Cc: Abner Chang <abner.chang@amd.com>
Cc: Paul Grimes <paul.grimes@amd.com>
Signed-off-by: Abdul Lateef Attar <AbdulLateef.Attar@amd.com>
---
 .../Library/PeiReportFvLib/PeiReportFvLib.c          | 12 +++++++++++-
 .../Library/SetCacheMtrrLib/SetCacheMtrrLib.c        |  3 +--
 2 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/Platform/AMD/AmdMinBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.c b/Platform/AMD/AmdMinBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.c
index f0b2abef61..b19f33663d 100644
--- a/Platform/AMD/AmdMinBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.c
+++ b/Platform/AMD/AmdMinBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.c
@@ -5,7 +5,7 @@
     This source has the reference of MinPlatformPkgs's PeriReportFvLib.c module.
 
   Copyright (c) 2018 - 2020, Intel Corporation. All rights reserved.<BR>
-  Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved
+  Copyright (C) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserved
   SPDX-License-Identifier: BSD-2-Clause-Patent
 
 **/
@@ -19,6 +19,11 @@
 #include <Guid/FirmwareFileSystem2.h>
 #include <Ppi/FirmwareVolumeInfo.h>
 
+/**
+  Report Pre-Memory Firmware Volumes.
+
+  This function reports the Pre-Memory Firmware Volumes to the Firmware Volume Hob.
+**/
 VOID
 ReportPreMemFv (
   VOID
@@ -66,6 +71,11 @@ ReportPreMemFv (
   }
 }
 
+/**
+  Report Post-Memory Firmware Volumes.
+
+  This function reports the Post-Memory Firmware Volumes to the Firmware Volume Hob.
+**/
 VOID
 ReportPostMemFv (
   VOID
diff --git a/Platform/AMD/AmdMinBoardPkg/Library/SetCacheMtrrLib/SetCacheMtrrLib.c b/Platform/AMD/AmdMinBoardPkg/Library/SetCacheMtrrLib/SetCacheMtrrLib.c
index 33b774fedb..e7a503f6cf 100644
--- a/Platform/AMD/AmdMinBoardPkg/Library/SetCacheMtrrLib/SetCacheMtrrLib.c
+++ b/Platform/AMD/AmdMinBoardPkg/Library/SetCacheMtrrLib/SetCacheMtrrLib.c
@@ -3,7 +3,7 @@
 SetCacheMtrr library functions.
 This library implementation is for AMD processor based platforms.
 
-Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.<BR>
+Copyright (C) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
 
 SPDX-License-Identifier: BSD-2-Clause-Patent
 
@@ -130,4 +130,3 @@ SetCacheMtrrAfterEndOfPei (
   MtrrDebugPrintAllMtrrs ();
   return EFI_SUCCESS;
 }
-
-- 
2.34.1



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



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [edk2-devel] [PATCH 3/5] AmdMinBoardPkg: Implement BoardInitLib for PEI phase
  2024-05-17  3:49 [edk2-devel] [PATCH 0/5] AmdMinBoardPkg: AMD board specific modules Abdul Lateef Attar via groups.io
  2024-05-17  3:49 ` [edk2-devel] [PATCH 1/5] AmdMinBoardPkg: Uncrustify PciHotPlug module Abdul Lateef Attar via groups.io
  2024-05-17  3:49 ` [edk2-devel] [PATCH 2/5] AmdMinBoardPkg/Library: Uncrustify the Library module Abdul Lateef Attar via groups.io
@ 2024-05-17  3:49 ` Abdul Lateef Attar via groups.io
  2024-05-17  3:49 ` [edk2-devel] [PATCH 4/5] AmdMinBoardPkg: Implement BoardInitLib for DXE phase Abdul Lateef Attar via groups.io
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Abdul Lateef Attar via groups.io @ 2024-05-17  3:49 UTC (permalink / raw)
  To: devel; +Cc: Abdul Lateef Attar, Abner Chang, Paul Grimes

PeiBoardInitPreMemLib library provides board-specific
initialization functions for the PEI phase.

Cc: Abner Chang <abner.chang@amd.com>
Cc: Paul Grimes <paul.grimes@amd.com>
Signed-off-by: Abdul Lateef Attar <AbdulLateef.Attar@amd.com>
---
 .../AMD/AmdMinBoardPkg/AmdMinBoardPkg.dsc     |   2 +
 .../PeiBoardInitPreMemLib/AmdMemoryInfoHob.h  |  50 ++++
 .../PeiBoardInitPreMemLib.c                   | 229 ++++++++++++++++++
 .../PeiBoardInitPreMemLib.inf                 |  45 ++++
 .../PeiBoardInitPreMemLib/PeiMemoryInit.c     | 198 +++++++++++++++
 .../PeiBoardInitPreMemLib/PeiMemoryInit.h     |  50 ++++
 6 files changed, 574 insertions(+)
 create mode 100644 Platform/AMD/AmdMinBoardPkg/Library/PeiBoardInitPreMemLib/AmdMemoryInfoHob.h
 create mode 100644 Platform/AMD/AmdMinBoardPkg/Library/PeiBoardInitPreMemLib/PeiBoardInitPreMemLib.c
 create mode 100644 Platform/AMD/AmdMinBoardPkg/Library/PeiBoardInitPreMemLib/PeiBoardInitPreMemLib.inf
 create mode 100644 Platform/AMD/AmdMinBoardPkg/Library/PeiBoardInitPreMemLib/PeiMemoryInit.c
 create mode 100644 Platform/AMD/AmdMinBoardPkg/Library/PeiBoardInitPreMemLib/PeiMemoryInit.h

diff --git a/Platform/AMD/AmdMinBoardPkg/AmdMinBoardPkg.dsc b/Platform/AMD/AmdMinBoardPkg/AmdMinBoardPkg.dsc
index be33089a45..335e875f70 100644
--- a/Platform/AMD/AmdMinBoardPkg/AmdMinBoardPkg.dsc
+++ b/Platform/AMD/AmdMinBoardPkg/AmdMinBoardPkg.dsc
@@ -38,6 +38,7 @@
 
 [LibraryClasses.common.PEIM]
   SetCacheMtrrLib|AmdMinBoardPkg/Library/SetCacheMtrrLib/SetCacheMtrrLib.inf
+  BoardInitLib|AmdMinBoardPkg/Library/PeiBoardInitPreMemLib/PeiBoardInitPreMemLib.inf
 
 [Components]
   AmdMinBoardPkg/Library/SpcrDeviceLib/SpcrDeviceLib.inf
@@ -45,6 +46,7 @@
 [Components.IA32]
   AmdMinBoardPkg/Library/SetCacheMtrrLib/SetCacheMtrrLib.inf
   AmdMinBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.inf
+  AmdMinBoardPkg/Library/PeiBoardInitPreMemLib/PeiBoardInitPreMemLib.inf
 
 [Components.X64]
   AmdMinBoardPkg/PciHotPlug/PciHotPlugInit.inf
diff --git a/Platform/AMD/AmdMinBoardPkg/Library/PeiBoardInitPreMemLib/AmdMemoryInfoHob.h b/Platform/AMD/AmdMinBoardPkg/Library/PeiBoardInitPreMemLib/AmdMemoryInfoHob.h
new file mode 100644
index 0000000000..b596b3bdf3
--- /dev/null
+++ b/Platform/AMD/AmdMinBoardPkg/Library/PeiBoardInitPreMemLib/AmdMemoryInfoHob.h
@@ -0,0 +1,50 @@
+/** @file
+  Defines AMD memory info hob.
+
+  Copyright (C) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserved.
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef AMD_MEMORY_INFO_HOB_H_
+#define AMD_MEMORY_INFO_HOB_H_
+
+#pragma pack (push, 1)
+
+/// Memory descriptor structure for each memory range
+typedef struct {
+  UINT64    Base;                           ///< Base address of memory rang
+  UINT64    Size;                           ///< Size of memory rang
+  UINT32    Attribute;                      ///< Attribute of memory rang
+  UINT32    Reserved;                       ///< For alignment purpose
+} AMD_MEMORY_RANGE_DESCRIPTOR;
+
+/// Memory info HOB structure
+typedef struct  {
+  UINT32                         Version;               ///< Version of HOB structure
+  BOOLEAN                        Reserved1;
+  UINT16                         Reserved2;
+  BOOLEAN                        Reserved3;
+  UINT8                          Reserved4;
+  BOOLEAN                        Reserved5;
+  UINT32                         Reserved6;
+  UINT32                         Reserved7;
+  UINT32                         NumberOfDescriptor;    ///< Number of memory range descriptor
+  AMD_MEMORY_RANGE_DESCRIPTOR    Ranges[1];             ///< Memory ranges array
+} AMD_MEMORY_INFO_HOB;
+
+#pragma pack (pop)
+
+/// Memory attribute in the memory range descriptor = AVAILABLE
+#define AMD_MEMORY_ATTRIBUTE_AVAILABLE  0x1
+
+/// Memory attribute in the memory range descriptor = UMA
+#define AMD_MEMORY_ATTRIBUTE_UMA  0x2
+
+/// Memory attribute in the memory range descriptor = MMIO
+#define AMD_MEMORY_ATTRIBUTE_MMIO  0x3
+
+/// Memory attribute in the memory range descriptor = RESERVED
+#define AMD_MEMORY_ATTRIBUTE_RESERVED  0x4
+
+#endif
diff --git a/Platform/AMD/AmdMinBoardPkg/Library/PeiBoardInitPreMemLib/PeiBoardInitPreMemLib.c b/Platform/AMD/AmdMinBoardPkg/Library/PeiBoardInitPreMemLib/PeiBoardInitPreMemLib.c
new file mode 100644
index 0000000000..01e73efa12
--- /dev/null
+++ b/Platform/AMD/AmdMinBoardPkg/Library/PeiBoardInitPreMemLib/PeiBoardInitPreMemLib.c
@@ -0,0 +1,229 @@
+/** @file
+  BoardInitLib library implementation for pre-mem PEI phase.
+
+Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/BoardInitLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include "PeiMemoryInit.h"
+
+EFI_PEI_NOTIFY_DESCRIPTOR  mNotifyList = {
+  (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+  &gAmdMemoryInfoHobPpiGuid,
+  EndofAmdMemoryInfoHobPpiGuidCallBack
+};
+
+/**
+  Get Pcie base address from MSR and set PcdPciExpressBaseSize
+
+  @retval EFI_SUCCESS   PcdPciExpressBaseSize value set successfully.
+**/
+EFI_STATUS
+EFIAPI
+SetPcieBaseSize (
+  VOID
+  )
+{
+  EFI_STATUS  Status;
+  UINT64      PcieBaseSize;
+  UINT8       BusRange;
+
+  Status = EFI_SUCCESS;
+
+  // Gather the value of PcdPciExpressBaseSize from MSR
+  BusRange     =  RShiftU64 (AsmReadMsr64 (0xC0010058), 2) & 0xF;
+  PcieBaseSize =  MultU64x64 (LShiftU64 (1, BusRange), SIZE_1MB);
+  PcdSet64S (PcdPciExpressBaseSize, (UINT64)PcieBaseSize);
+  return Status;
+}
+
+/**
+  This board service detects the board type.
+
+  @retval EFI_SUCCESS   The board was detected successfully.
+  @retval EFI_NOT_FOUND The board could not be detected.
+**/
+EFI_STATUS
+EFIAPI
+BoardDetect (
+  VOID
+  )
+{
+  return EFI_SUCCESS;
+}
+
+/**
+  This board service initializes board-specific debug devices.
+
+  @retval EFI_SUCCESS   Board-specific debug initialization was successful.
+  @retval EFI_NOT_READY The board has not been detected yet.
+**/
+EFI_STATUS
+EFIAPI
+BoardDebugInit (
+  VOID
+  )
+{
+  return EFI_SUCCESS;
+}
+
+/**
+  This board service detects the boot mode.
+
+  @retval EFI_BOOT_MODE The boot mode.
+  @retval EFI_NOT_READY The board has not been detected yet.
+**/
+EFI_BOOT_MODE
+EFIAPI
+BoardBootModeDetect (
+  VOID
+  )
+{
+  return BOOT_WITH_FULL_CONFIGURATION;
+}
+
+/**
+  A hook for board-specific initialization prior to memory initialization.
+
+  @retval EFI_SUCCESS   The board initialization was successful.
+  @retval EFI_NOT_READY The board has not been detected yet.
+**/
+EFI_STATUS
+EFIAPI
+BoardInitBeforeMemoryInit (
+  VOID
+  )
+{
+  EFI_STATUS  Status;
+
+  Status = PeiServicesNotifyPpi (&mNotifyList);
+  ASSERT_EFI_ERROR (Status);
+  Status = SetPcieBaseSize ();
+  ASSERT_EFI_ERROR (Status);
+  return (Status);
+}
+
+/**
+  A hook for board-specific initialization after memory initialization.
+
+  @retval EFI_SUCCESS   The board initialization was successful.
+  @retval EFI_NOT_READY The board has not been detected yet.
+**/
+EFI_STATUS
+EFIAPI
+BoardInitAfterMemoryInit (
+  VOID
+  )
+{
+  return EFI_SUCCESS;
+}
+
+/**
+  A hook for board-specific initialization prior to disabling temporary RAM.
+
+  @retval EFI_SUCCESS   The board initialization was successful.
+  @retval EFI_NOT_READY The board has not been detected yet.
+**/
+EFI_STATUS
+EFIAPI
+BoardInitBeforeTempRamExit (
+  VOID
+  )
+{
+  return EFI_SUCCESS;
+}
+
+/**
+  A hook for board-specific initialization after disabling temporary RAM.
+
+  @retval EFI_SUCCESS   The board initialization was successful.
+  @retval EFI_NOT_READY The board has not been detected yet.
+**/
+EFI_STATUS
+EFIAPI
+BoardInitAfterTempRamExit (
+  VOID
+  )
+{
+  return EFI_SUCCESS;
+}
+
+/**
+  A hook for board-specific initialization prior to silicon initialization.
+
+  @retval EFI_SUCCESS   The board initialization was successful.
+  @retval EFI_NOT_READY The board has not been detected yet.
+**/
+EFI_STATUS
+EFIAPI
+BoardInitBeforeSiliconInit (
+  VOID
+  )
+{
+  return EFI_SUCCESS;
+}
+
+/**
+  A hook for board-specific initialization after silicon initialization.
+
+  @retval EFI_SUCCESS   The board initialization was successful.
+  @retval EFI_NOT_READY The board has not been detected yet.
+**/
+EFI_STATUS
+EFIAPI
+BoardInitAfterSiliconInit (
+  VOID
+  )
+{
+  return EFI_SUCCESS;
+}
+
+/**
+  A hook for board-specific initialization after PCI enumeration.
+
+  @retval EFI_SUCCESS   The board initialization was successful.
+  @retval EFI_NOT_READY The board has not been detected yet.
+**/
+EFI_STATUS
+EFIAPI
+BoardInitAfterPciEnumeration (
+  VOID
+  )
+{
+  return EFI_SUCCESS;
+}
+
+/**
+  A hook for board-specific functionality for the ReadyToBoot event.
+
+  @retval EFI_SUCCESS   The board initialization was successful.
+  @retval EFI_NOT_READY The board has not been detected yet.
+**/
+EFI_STATUS
+EFIAPI
+BoardInitReadyToBoot (
+  VOID
+  )
+{
+  return EFI_SUCCESS;
+}
+
+/**
+  A hook for board-specific functionality for the ExitBootServices event.
+
+  @retval EFI_SUCCESS   The board initialization was successful.
+  @retval EFI_NOT_READY The board has not been detected yet.
+**/
+EFI_STATUS
+EFIAPI
+BoardInitEndOfFirmware (
+  VOID
+  )
+{
+  return EFI_SUCCESS;
+}
diff --git a/Platform/AMD/AmdMinBoardPkg/Library/PeiBoardInitPreMemLib/PeiBoardInitPreMemLib.inf b/Platform/AMD/AmdMinBoardPkg/Library/PeiBoardInitPreMemLib/PeiBoardInitPreMemLib.inf
new file mode 100644
index 0000000000..5bc19e6834
--- /dev/null
+++ b/Platform/AMD/AmdMinBoardPkg/Library/PeiBoardInitPreMemLib/PeiBoardInitPreMemLib.inf
@@ -0,0 +1,45 @@
+## @file
+# Board Init Library for AMD Platforms.
+#
+# Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 1.29
+  BASE_NAME                      = PeiBoardInitPreMemLib
+  FILE_GUID                      = A394D6BE-4433-4564-8FEB-2C90DD9ECE5B
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = BoardInitLib
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  HobLib
+  PcdLib
+
+[Packages]
+  AmdMinBoardPkg/AmdMinBoardPkg.dec
+  MdePkg/MdePkg.dec
+  MinPlatformPkg/MinPlatformPkg.dec
+
+[Sources]
+  AmdMemoryInfoHob.h
+  PeiMemoryInit.h
+  PeiBoardInitPreMemLib.c
+  PeiMemoryInit.c
+
+[Guids]
+  gAmdMemoryInfoHobGuid
+  gEfiSmmSmramMemoryGuid
+
+[Ppis]
+  gAmdMemoryInfoHobPpiGuid                                          ## CONSUMES
+  gPeiPlatformMemorySizePpiGuid                                     ## CONSUMES
+
+[Pcd]
+  gAmdMinBoardPkgTokenSpaceGuid.PcdAmdSmramAreaSize
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseSize                    ## CONSUMES
diff --git a/Platform/AMD/AmdMinBoardPkg/Library/PeiBoardInitPreMemLib/PeiMemoryInit.c b/Platform/AMD/AmdMinBoardPkg/Library/PeiBoardInitPreMemLib/PeiMemoryInit.c
new file mode 100644
index 0000000000..03f08214e2
--- /dev/null
+++ b/Platform/AMD/AmdMinBoardPkg/Library/PeiBoardInitPreMemLib/PeiMemoryInit.c
@@ -0,0 +1,198 @@
+/** @file
+
+Copyright (C) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserved
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "PeiMemoryInit.h"
+#include "AmdMemoryInfoHob.h"
+
+/**
+  A Callback routine only AmdMemoryInfoHob is ready.
+
+  @param[in]  PeiServices       General purpose services available to every PEIM.
+  @param[in]  NotifyDescriptor  The descriptor for the notification event.
+  @param[in]  Ppi               The context of the notification.
+
+  @retval EFI_SUCCESS   Platform Pre Memory initialization is successful.
+          EFI_STATUS    Various failure from underlying routine calls.
+**/
+EFI_STATUS
+EFIAPI
+EndofAmdMemoryInfoHobPpiGuidCallBack (
+  IN EFI_PEI_SERVICES           **PeiServices,
+  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
+  IN VOID                       *Ppi
+  )
+{
+  PEI_PLATFORM_MEMORY_SIZE_PPI    *PlatformMemorySizePpi;
+  EFI_STATUS                      Status;
+  UINT64                          MemorySize;
+  AMD_MEMORY_INFO_HOB             *AmdMemoryInfoHob;
+  AMD_MEMORY_RANGE_DESCRIPTOR     *AmdMemoryInfoRange;
+  EFI_HOB_GUID_TYPE               *GuidHob;
+  EFI_PEI_HOB_POINTERS            Hob;
+  UINTN                           Index;
+  EFI_SMRAM_HOB_DESCRIPTOR_BLOCK  *SmramHobDescriptorBlock;
+  EFI_PHYSICAL_ADDRESS            SmramBaseAddress;
+  UINT8                           SmramRanges;
+  UINTN                           DataSize;
+
+  SmramBaseAddress = 0;
+  SmramRanges      = 0;
+
+  // Locate AMD_MEMORY_INFO_HOB Guided HOB and retrieve data
+  AmdMemoryInfoHob = NULL;
+  GuidHob          = GetFirstGuidHob (&gAmdMemoryInfoHobGuid);
+  if (GuidHob != NULL) {
+    AmdMemoryInfoHob = GET_GUID_HOB_DATA (GuidHob);
+  }
+
+  if (AmdMemoryInfoHob == NULL) {
+    DEBUG ((DEBUG_ERROR, "Error: Could not locate AMD_MEMORY_INFO_HOB.\n"));
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  DEBUG ((DEBUG_INFO, "AMD_MEMORY_INFO_HOB at 0x%X\n", AmdMemoryInfoHob));
+  DEBUG ((DEBUG_INFO, "  Version: 0x%X\n", AmdMemoryInfoHob->Version));
+  DEBUG ((DEBUG_INFO, "  NumberOfDescriptor: 0x%X\n", AmdMemoryInfoHob->NumberOfDescriptor));
+
+  //
+  // Build Descriptors
+  //
+  DEBUG ((DEBUG_INFO, "\nAMD HOB Descriptors:"));
+  for (Index = 0; Index < AmdMemoryInfoHob->NumberOfDescriptor; Index++) {
+    AmdMemoryInfoRange = (AMD_MEMORY_RANGE_DESCRIPTOR *)&(AmdMemoryInfoHob->Ranges[Index]);
+
+    DEBUG ((DEBUG_INFO, "\n Index: %d\n", Index));
+    DEBUG ((DEBUG_INFO, "   Base: 0x%lX\n", AmdMemoryInfoRange->Base));
+    DEBUG ((DEBUG_INFO, "   Size: 0x%lX\n", AmdMemoryInfoRange->Size));
+    DEBUG ((DEBUG_INFO, "   Attribute: 0x%X\n", AmdMemoryInfoRange->Attribute));
+
+    switch (AmdMemoryInfoRange->Attribute) {
+      case AMD_MEMORY_ATTRIBUTE_AVAILABLE:
+        if (AmdMemoryInfoRange->Base < SIZE_4GB) {
+          SmramRanges = 1u;
+          // Set SMRAM base at heighest range below 4GB
+          SmramBaseAddress = AmdMemoryInfoRange->Base + AmdMemoryInfoRange->Size - FixedPcdGet32 (PcdAmdSmramAreaSize);
+          BuildResourceDescriptorHob (
+            EFI_RESOURCE_MEMORY_RESERVED,
+            (EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
+            SmramBaseAddress,
+            FixedPcdGet32 (PcdAmdSmramAreaSize)
+            );
+          DEBUG ((
+            DEBUG_INFO,
+            "SMRAM RESERVED_MEMORY: Base = 0x%lX, Size = 0x%lX\n",
+            SmramBaseAddress,
+            FixedPcdGet32 (PcdAmdSmramAreaSize)
+            ));
+
+          AmdMemoryInfoRange->Size -= FixedPcdGet32 (PcdAmdSmramAreaSize);
+        }
+
+        if (AmdMemoryInfoRange->Size) {
+          BuildResourceDescriptorHob (
+            EFI_RESOURCE_SYSTEM_MEMORY,
+            SYSTEM_MEMORY_ATTRIBUTES,
+            AmdMemoryInfoRange->Base,
+            AmdMemoryInfoRange->Size
+            );
+
+          DEBUG ((
+            DEBUG_INFO,
+            "SYSTEM_MEMORY: Base = 0x%lX, Size = 0x%lX\n",
+            AmdMemoryInfoRange->Base,
+            AmdMemoryInfoRange->Size
+            ));
+        }
+
+        break;
+
+      case AMD_MEMORY_ATTRIBUTE_MMIO:
+        BuildResourceDescriptorHob (
+          EFI_RESOURCE_MEMORY_MAPPED_IO,
+          MEMORY_MAPPED_IO_ATTRIBUTES,
+          AmdMemoryInfoRange->Base,
+          AmdMemoryInfoRange->Size
+          );
+
+        DEBUG ((
+          DEBUG_INFO,
+          "MMIO: Base = 0x%lX, Size = 0x%lX\n",
+          AmdMemoryInfoRange->Base,
+          AmdMemoryInfoRange->Size
+          ));
+        break;
+
+      case AMD_MEMORY_ATTRIBUTE_RESERVED:
+      case AMD_MEMORY_ATTRIBUTE_UMA:
+      default:
+        BuildResourceDescriptorHob (
+          EFI_RESOURCE_MEMORY_RESERVED,
+          0,
+          AmdMemoryInfoRange->Base,
+          AmdMemoryInfoRange->Size
+          );
+
+        DEBUG ((
+          DEBUG_INFO,
+          "RESERVED_MEMORY: Base = 0x%lX, Size = 0x%lX\n",
+          AmdMemoryInfoRange->Base,
+          AmdMemoryInfoRange->Size
+          ));
+        break;
+    }
+  }
+
+  ASSERT (SmramRanges > 0);
+  DataSize  = sizeof (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK);
+  DataSize += ((SmramRanges - 1) * sizeof (EFI_SMRAM_DESCRIPTOR));
+
+  Hob.Raw = BuildGuidHob (
+              &gEfiSmmSmramMemoryGuid,
+              DataSize
+              );
+  ASSERT (Hob.Raw);
+
+  SmramHobDescriptorBlock                              = (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *)(Hob.Raw);
+  SmramHobDescriptorBlock->NumberOfSmmReservedRegions  = SmramRanges;
+  SmramHobDescriptorBlock->Descriptor[0].PhysicalStart = SmramBaseAddress;
+  SmramHobDescriptorBlock->Descriptor[0].CpuStart      = SmramBaseAddress;
+  SmramHobDescriptorBlock->Descriptor[0].PhysicalSize  = FixedPcdGet32 (PcdAmdSmramAreaSize);
+  SmramHobDescriptorBlock->Descriptor[0].RegionState   = EFI_SMRAM_CLOSED | EFI_CACHEABLE;
+
+  Status = PeiServicesLocatePpi (
+             &gPeiPlatformMemorySizePpiGuid,
+             0,
+             NULL,
+             (VOID **)&PlatformMemorySizePpi
+             );
+  ASSERT_EFI_ERROR (Status);
+
+  Status = PlatformMemorySizePpi->GetPlatformMemorySize (
+                                    PeiServices,
+                                    PlatformMemorySizePpi,
+                                    &MemorySize
+                                    );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "%a: Error(%r) in getting Platform Memory size.\n",
+      __func__,
+      Status
+      ));
+    return Status;
+  }
+
+  DEBUG ((
+    DEBUG_INFO,
+    "Installing PeiMemory, BaseAddress = 0x%x, Size = 0x%x\n",
+    0,
+    MemorySize
+    ));
+  Status = PeiServicesInstallPeiMemory (0, MemorySize);
+  ASSERT_EFI_ERROR (Status);
+  return Status;
+}
diff --git a/Platform/AMD/AmdMinBoardPkg/Library/PeiBoardInitPreMemLib/PeiMemoryInit.h b/Platform/AMD/AmdMinBoardPkg/Library/PeiBoardInitPreMemLib/PeiMemoryInit.h
new file mode 100644
index 0000000000..726db25543
--- /dev/null
+++ b/Platform/AMD/AmdMinBoardPkg/Library/PeiBoardInitPreMemLib/PeiMemoryInit.h
@@ -0,0 +1,50 @@
+/** @file
+  This file contains definitions required for memory initialization in PEI phase.
+
+  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef PEI_MEMORY_INIT_PEI_H_
+#define PEI_MEMORY_INIT_PEI_H_
+
+#include <Uefi/UefiBaseType.h>
+#include <Pi/PiPeiCis.h>
+#include <Library/PeiServicesLib.h>
+#include <Ppi/PlatformMemorySize.h>
+#include <Guid/SmramMemoryReserve.h>
+#include <Library/HobLib.h>
+#include <Library/DebugLib.h>
+
+#define SYSTEM_MEMORY_ATTRIBUTES  (                \
+  EFI_RESOURCE_ATTRIBUTE_PRESENT |                 \
+  EFI_RESOURCE_ATTRIBUTE_INITIALIZED |             \
+  EFI_RESOURCE_ATTRIBUTE_TESTED |                  \
+  EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |             \
+  EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |       \
+  EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE | \
+  EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE      \
+  )
+
+#define MEMORY_MAPPED_IO_ATTRIBUTES  ( \
+  EFI_RESOURCE_ATTRIBUTE_PRESENT |     \
+  EFI_RESOURCE_ATTRIBUTE_INITIALIZED | \
+  EFI_RESOURCE_ATTRIBUTE_TESTED |      \
+  EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE   \
+  )
+
+/**
+  A Callback routine only AmdMemoryInfoHob is ready.
+
+  @retval EFI_SUCCESS   Platform Pre Memory initialization is successfull.
+          EFI_STATUS    Various failure from underlying routine calls.
+**/
+EFI_STATUS
+EFIAPI
+EndofAmdMemoryInfoHobPpiGuidCallBack (
+  IN EFI_PEI_SERVICES           **PeiServices,
+  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
+  IN VOID                       *Ppi
+  );
+
+#endif // PEI_MEMORY_INIT_PEI_H_
-- 
2.34.1



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



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [edk2-devel] [PATCH 4/5] AmdMinBoardPkg: Implement BoardInitLib for DXE phase
  2024-05-17  3:49 [edk2-devel] [PATCH 0/5] AmdMinBoardPkg: AMD board specific modules Abdul Lateef Attar via groups.io
                   ` (2 preceding siblings ...)
  2024-05-17  3:49 ` [edk2-devel] [PATCH 3/5] AmdMinBoardPkg: Implement BoardInitLib for PEI phase Abdul Lateef Attar via groups.io
@ 2024-05-17  3:49 ` Abdul Lateef Attar via groups.io
  2024-05-17  3:49 ` [edk2-devel] [PATCH 5/5] AmdMinBoardPkg: Implements BoardBdsHookLib library Abdul Lateef Attar via groups.io
  2024-05-17  5:53 ` [edk2-devel] [PATCH 0/5] AmdMinBoardPkg: AMD board specific modules Chang, Abner via groups.io
  5 siblings, 0 replies; 7+ messages in thread
From: Abdul Lateef Attar via groups.io @ 2024-05-17  3:49 UTC (permalink / raw)
  To: devel; +Cc: Abdul Lateef Attar, Abner Chang, Paul Grimes

DxeBoardInitLib library provides board-specific
initialization functions for the DXE phase.

Cc: Abner Chang <abner.chang@amd.com>
Cc: Paul Grimes <paul.grimes@amd.com>
Signed-off-by: Abdul Lateef Attar <AbdulLateef.Attar@amd.com>
---
 .../AMD/AmdMinBoardPkg/AmdMinBoardPkg.dsc     |   6 +-
 .../Library/DxeBoardInitLib/DxeBoardInitLib.c | 253 +++++++++++++++
 .../DxeBoardInitLib/DxeBoardInitLib.inf       |  51 +++
 .../DxeBoardInitLib/DxeBoardInitLibInternal.c | 306 ++++++++++++++++++
 .../DxeBoardInitLib/DxeBoardInitLibInternal.h | 159 +++++++++
 .../DxeBoardInitLib/MadtAcpiTablePatch.c      | 243 ++++++++++++++
 6 files changed, 1017 insertions(+), 1 deletion(-)
 create mode 100644 Platform/AMD/AmdMinBoardPkg/Library/DxeBoardInitLib/DxeBoardInitLib.c
 create mode 100644 Platform/AMD/AmdMinBoardPkg/Library/DxeBoardInitLib/DxeBoardInitLib.inf
 create mode 100644 Platform/AMD/AmdMinBoardPkg/Library/DxeBoardInitLib/DxeBoardInitLibInternal.c
 create mode 100644 Platform/AMD/AmdMinBoardPkg/Library/DxeBoardInitLib/DxeBoardInitLibInternal.h
 create mode 100644 Platform/AMD/AmdMinBoardPkg/Library/DxeBoardInitLib/MadtAcpiTablePatch.c

diff --git a/Platform/AMD/AmdMinBoardPkg/AmdMinBoardPkg.dsc b/Platform/AMD/AmdMinBoardPkg/AmdMinBoardPkg.dsc
index 335e875f70..e0afe1e755 100644
--- a/Platform/AMD/AmdMinBoardPkg/AmdMinBoardPkg.dsc
+++ b/Platform/AMD/AmdMinBoardPkg/AmdMinBoardPkg.dsc
@@ -40,6 +40,9 @@
   SetCacheMtrrLib|AmdMinBoardPkg/Library/SetCacheMtrrLib/SetCacheMtrrLib.inf
   BoardInitLib|AmdMinBoardPkg/Library/PeiBoardInitPreMemLib/PeiBoardInitPreMemLib.inf
 
+[LibraryClasses.common.DXE_DRIVER]
+  BoardInitLib|AmdMinBoardPkg/Library/DxeBoardInitLib/DxeBoardInitLib.inf
+
 [Components]
   AmdMinBoardPkg/Library/SpcrDeviceLib/SpcrDeviceLib.inf
 
@@ -49,4 +52,5 @@
   AmdMinBoardPkg/Library/PeiBoardInitPreMemLib/PeiBoardInitPreMemLib.inf
 
 [Components.X64]
-  AmdMinBoardPkg/PciHotPlug/PciHotPlugInit.inf
+  AmdMinBoardPkg/Library/DxeBoardInitLib/DxeBoardInitLib.inf
+  AmdMinBoardPkg/PciHotPlug/PciHotPlugInit.inf
\ No newline at end of file
diff --git a/Platform/AMD/AmdMinBoardPkg/Library/DxeBoardInitLib/DxeBoardInitLib.c b/Platform/AMD/AmdMinBoardPkg/Library/DxeBoardInitLib/DxeBoardInitLib.c
new file mode 100644
index 0000000000..7c41d3e38b
--- /dev/null
+++ b/Platform/AMD/AmdMinBoardPkg/Library/DxeBoardInitLib/DxeBoardInitLib.c
@@ -0,0 +1,253 @@
+/** @file
+  BoardInitLib library implementation for DXE phase.
+
+  Copyright (C) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/BoardInitLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include "DxeBoardInitLibInternal.h"
+
+EFI_HANDLE        mImageHandle;
+EFI_SYSTEM_TABLE  *mSystemTable;
+
+/**
+  This board service detects the board type.
+
+  @retval EFI_SUCCESS   The board was detected successfully.
+  @retval EFI_NOT_FOUND The board could not be detected.
+**/
+EFI_STATUS
+EFIAPI
+BoardDetect (
+  VOID
+  )
+{
+  return EFI_SUCCESS;
+}
+
+/**
+  This board service initializes board-specific debug devices.
+
+  @retval EFI_SUCCESS   Board-specific debug initialization was successful.
+  @retval EFI_NOT_READY The board has not been detected yet.
+**/
+EFI_STATUS
+EFIAPI
+BoardDebugInit (
+  VOID
+  )
+{
+  return EFI_SUCCESS;
+}
+
+/**
+  This board service detects the boot mode.
+
+  @retval EFI_BOOT_MODE The boot mode.
+  @retval EFI_NOT_READY The board has not been detected yet.
+**/
+EFI_BOOT_MODE
+EFIAPI
+BoardBootModeDetect (
+  VOID
+  )
+{
+  return BOOT_WITH_FULL_CONFIGURATION;
+}
+
+/**
+  A hook for board-specific initialization prior to memory initialization.
+
+  @retval EFI_SUCCESS   The board initialization was successful.
+  @retval EFI_NOT_READY The board has not been detected yet.
+**/
+EFI_STATUS
+EFIAPI
+BoardInitBeforeMemoryInit (
+  VOID
+  )
+{
+  return EFI_SUCCESS;
+}
+
+/**
+  A hook for board-specific initialization after memory initialization.
+
+  @retval EFI_SUCCESS   The board initialization was successful.
+  @retval EFI_NOT_READY The board has not been detected yet.
+**/
+EFI_STATUS
+EFIAPI
+BoardInitAfterMemoryInit (
+  VOID
+  )
+{
+  return EFI_SUCCESS;
+}
+
+/**
+  A hook for board-specific initialization prior to disabling temporary RAM.
+
+  @retval EFI_SUCCESS   The board initialization was successful.
+  @retval EFI_NOT_READY The board has not been detected yet.
+**/
+EFI_STATUS
+EFIAPI
+BoardInitBeforeTempRamExit (
+  VOID
+  )
+{
+  return EFI_SUCCESS;
+}
+
+/**
+  A hook for board-specific initialization after disabling temporary RAM.
+
+  @retval EFI_SUCCESS   The board initialization was successful.
+  @retval EFI_NOT_READY The board has not been detected yet.
+**/
+EFI_STATUS
+EFIAPI
+BoardInitAfterTempRamExit (
+  VOID
+  )
+{
+  return EFI_SUCCESS;
+}
+
+/**
+  A hook for board-specific initialization prior to silicon initialization.
+
+  @retval EFI_SUCCESS   The board initialization was successful.
+  @retval EFI_NOT_READY The board has not been detected yet.
+**/
+EFI_STATUS
+EFIAPI
+BoardInitBeforeSiliconInit (
+  VOID
+  )
+{
+  return EFI_SUCCESS;
+}
+
+/**
+  A hook for board-specific initialization after silicon initialization.
+
+  @retval EFI_SUCCESS   The board initialization was successful.
+  @retval EFI_NOT_READY The board has not been detected yet.
+**/
+EFI_STATUS
+EFIAPI
+BoardInitAfterSiliconInit (
+  VOID
+  )
+{
+  return EFI_SUCCESS;
+}
+
+/**
+  A hook for board-specific initialization after PCI enumeration.
+
+  @retval EFI_SUCCESS   The board initialization was successful.
+  @retval EFI_NOT_READY The board has not been detected yet.
+**/
+EFI_STATUS
+EFIAPI
+BoardInitAfterPciEnumeration (
+  VOID
+  )
+{
+  EFI_STATUS  Status;
+
+  DEBUG ((DEBUG_INFO, "%a - ENTRY\n", __FUNCTION__));
+
+  Status = ReserveLegacyVgaIoSpace ();
+  DEBUG ((DEBUG_INFO, "ReserveLegacyVgaIoSpace...%r.\n", Status));
+
+  Status = ReservePcieExtendedConfigSpace (mImageHandle, mSystemTable);
+  DEBUG ((DEBUG_INFO, "ReservePcieExtendedConfigSpace...%r.\n", Status));
+
+  return Status;
+}
+
+/**
+  A hook for board-specific functionality for the ReadyToBoot event.
+
+  @retval EFI_SUCCESS   The board initialization was successful.
+  @retval EFI_NOT_READY The board has not been detected yet.
+**/
+EFI_STATUS
+EFIAPI
+BoardInitReadyToBoot (
+  VOID
+  )
+{
+  EFI_STATUS  Status;
+
+  Status = UpdateReinstallAcpiTable (
+             EFI_ACPI_6_5_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE,
+             (PATCH_ACPITABLE)FadtAcpiTablePatch
+             );
+  DEBUG ((DEBUG_INFO, "Patching FADT ACPI Table ... Status = %r.\n", Status));
+
+  Status = UpdateReinstallAcpiTable (
+             EFI_ACPI_6_5_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE,
+             (PATCH_ACPITABLE)MadtAcpiTablePatch
+             );
+  DEBUG ((DEBUG_INFO, "Patching MADT ACPI Table ... Status = %r.\n", Status));
+
+  UpdateReinstallAcpiTable (
+    EFI_ACPI_6_5_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE,
+    (PATCH_ACPITABLE)AcpiTableAmlUpdate
+    );
+
+  UpdateReinstallAcpiTable (
+    EFI_ACPI_6_5_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE,
+    (PATCH_ACPITABLE)AcpiTableAmlUpdate
+    );
+
+  return EFI_SUCCESS;
+}
+
+/**
+  A hook for board-specific functionality for the ExitBootServices event.
+
+  @retval EFI_SUCCESS   The board initialization was successful.
+  @retval EFI_NOT_READY The board has not been detected yet.
+**/
+EFI_STATUS
+EFIAPI
+BoardInitEndOfFirmware (
+  VOID
+  )
+{
+  return EFI_SUCCESS;
+}
+
+/**
+  The constructor function caches the PCI Express Base Address and creates a
+  Set Virtual Address Map event to convert physical address to virtual addresses.
+
+  @param  ImageHandle   The firmware allocated handle for the EFI image.
+  @param  SystemTable   A pointer to the EFI System Table.
+
+  @retval EFI_SUCCESS   The constructor completed successfully.
+  @retval Other value   The constructor did not complete successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+DxeBoardInitLibConstructor (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  mImageHandle = ImageHandle;
+  mSystemTable = SystemTable;
+  return EFI_SUCCESS;
+}
diff --git a/Platform/AMD/AmdMinBoardPkg/Library/DxeBoardInitLib/DxeBoardInitLib.inf b/Platform/AMD/AmdMinBoardPkg/Library/DxeBoardInitLib/DxeBoardInitLib.inf
new file mode 100644
index 0000000000..919777d016
--- /dev/null
+++ b/Platform/AMD/AmdMinBoardPkg/Library/DxeBoardInitLib/DxeBoardInitLib.inf
@@ -0,0 +1,51 @@
+## @file
+#  Implements BoardInitLib Library Class in DXE phase.
+#
+# Copyright (C) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+  INF_VERSION                    = 1.29
+  BASE_NAME                      = DxeBoardInitLib
+  FILE_GUID                      = B3C8F348-B528-4CA0-928E-3193ADEA65E6
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = BoardInitLib
+  CONSTRUCTOR                    = DxeBoardInitLibConstructor
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  LocalApicLib
+  PcdLib
+  PcieConfigLib
+  PlatformSocLib
+  SortLib
+
+[Packages]
+  AmdPlatformPkg/AmdPlatformPkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  MinPlatformPkg/MinPlatformPkg.dec
+  PcAtChipsetPkg/PcAtChipsetPkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
+
+[Sources]
+  DxeBoardInitLib.c
+  DxeBoardInitLibInternal.c
+  DxeBoardInitLibInternal.h
+  MadtAcpiTablePatch.c
+
+[Protocols]
+  gEfiAcpiSdtProtocolGuid
+  gEfiAcpiTableProtocolGuid
+  gEfiMpServiceProtocolGuid
+
+[Pcd]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemTableId
+  gMinPlatformPkgTokenSpaceGuid.PcdMaxCpuSocketCount
+
+[DEPEX]
+  gEfiMpServiceProtocolGuid
diff --git a/Platform/AMD/AmdMinBoardPkg/Library/DxeBoardInitLib/DxeBoardInitLibInternal.c b/Platform/AMD/AmdMinBoardPkg/Library/DxeBoardInitLib/DxeBoardInitLibInternal.c
new file mode 100644
index 0000000000..2ffc249792
--- /dev/null
+++ b/Platform/AMD/AmdMinBoardPkg/Library/DxeBoardInitLib/DxeBoardInitLibInternal.c
@@ -0,0 +1,306 @@
+/** @file
+  BoardInitLib library internal implementation for DXE phase.
+
+Copyright (C) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserved
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#include "DxeBoardInitLibInternal.h"
+
+/**
+  A helper function to uninstall or update the ACPI table.
+  It searches for ACPI table for provided table signature,
+  if found then creates a copy of the table and calls the callbackfunction.
+
+  @param[in] Signature           ACPI table signature
+  @param[in] CallbackFunction    The function to call to patch the searching ACPI table.
+                                 If NULL then uninstalls the table.
+
+  @return EFI_SUCCESS            Successfully Re-install the ACPI Table
+  @return EFI_NOT_FOUND          Table not found
+  @return EFI_STATUS             returns non-EFI_SUCCESS value in case of failure
+
+**/
+EFI_STATUS
+EFIAPI
+UpdateReinstallAcpiTable (
+  IN UINT32           Signature,
+  IN PATCH_ACPITABLE  CallbackFunction
+  )
+{
+  EFI_ACPI_SDT_PROTOCOL    *AcpiSdtProtocol;
+  EFI_STATUS               Status;
+  UINTN                    Index;
+  EFI_ACPI_SDT_HEADER      *Table;
+  EFI_ACPI_TABLE_VERSION   Version;
+  UINTN                    OriginalTableKey;
+  EFI_ACPI_TABLE_PROTOCOL  *AcpiTableProtocol;
+  EFI_ACPI_SDT_HEADER      *NewTable;
+  UINTN                    NewTableKey;
+  BOOLEAN                  Found;
+
+  Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **)&AcpiTableProtocol);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Error(%r): Unable to locate ACPI Table protocol.\n", Status));
+    return Status;
+  }
+
+  Status = gBS->LocateProtocol (&gEfiAcpiSdtProtocolGuid, NULL, (VOID **)&AcpiSdtProtocol);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Error(%r): Unable to locate ACPI SDT protocol.\n", Status));
+    return Status;
+  }
+
+  Found = FALSE;
+  Index = 0;
+  do {
+    Status = AcpiSdtProtocol->GetAcpiTable (Index, &Table, &Version, &OriginalTableKey);
+    if (EFI_ERROR (Status)) {
+      goto END_OF_SEARCH;
+    }
+
+    // Look for given table
+    if (Table->Signature == Signature) {
+      if (CallbackFunction == NULL) {
+        Status = AcpiTableProtocol->UninstallAcpiTable (AcpiTableProtocol, OriginalTableKey);
+        return Status;
+      }
+
+      NewTable = AllocateCopyPool (Table->Length, Table);
+      if (NULL == NewTable) {
+        Status = EFI_OUT_OF_RESOURCES;
+        DEBUG ((DEBUG_ERROR, "Error(%r): Not enough resource to allocate table.\n", Status));
+        return Status;
+      }
+
+      Status = CallbackFunction (NewTable);
+      if (!EFI_ERROR (Status)) {
+        // Uninstall the old table
+        Status = AcpiTableProtocol->UninstallAcpiTable (AcpiTableProtocol, OriginalTableKey);
+        if (EFI_ERROR (Status)) {
+          DEBUG ((DEBUG_ERROR, "Error(%r): Uninstall old table error.\n", Status));
+          FreePool (NewTable);
+          return Status;
+        }
+
+        // Install the new table
+        Status = AcpiTableProtocol->InstallAcpiTable (AcpiTableProtocol, NewTable, NewTable->Length, &NewTableKey);
+        FreePool (NewTable);
+        if (EFI_ERROR (Status)) {
+          DEBUG ((DEBUG_ERROR, "Error(%r): Failed to install new table.\n", Status));
+          return Status;
+        }
+
+        // If non SSDT table, then return status
+        if (Table->Signature != EFI_ACPI_6_5_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE) {
+          return Status;
+        }
+
+        // Atleast one SSDT table update is success
+        Found = TRUE;
+      }
+
+      // continue to search next SSDT table.
+      Status = EFI_SUCCESS;
+    }
+
+    Index++;
+  } while (!EFI_ERROR (Status));
+
+END_OF_SEARCH:
+  if (!Found) {
+    DEBUG ((DEBUG_ERROR, "Error(%r): Unable to locate ACPI Table.\n", Status));
+    return EFI_NOT_FOUND;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  A Callback function to patch the ACPI FADT table.
+  Updates FADT table with AMD specific values, which
+  are different than MinPlatformPkg.
+
+  @param[in, out] NewTable       Pointer to ACPI FADT table
+
+  @return         EFI_SUCCESS    Always return EFI_SUCCESSe
+
+**/
+EFI_STATUS
+EFIAPI
+FadtAcpiTablePatch (
+  IN OUT  EFI_ACPI_SDT_HEADER  *NewTable
+  )
+{
+  EFI_ACPI_6_5_FIXED_ACPI_DESCRIPTION_TABLE  *NewFadt;
+
+  NewFadt = (EFI_ACPI_6_5_FIXED_ACPI_DESCRIPTION_TABLE *)NewTable;
+  // Patch the Table
+  NewFadt->PLvl2Lat                  = 0x64;
+  NewFadt->Pm2CntLen                 = 0;
+  NewFadt->XGpe0Blk.RegisterBitWidth = 0x40;
+  NewFadt->FlushSize                 = 0x400;
+  NewFadt->FlushStride               = 0x10;
+  NewFadt->XGpe1Blk.AccessSize       = 0x01;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  A Callback function to patch the ACPI DSDT/SSDT table.
+  Which has ASL code that needs to be updated.
+
+  @param[in, out] NewTable       Pointer to ACPI FADT table
+
+  @return         EFI_SUCCESS    If table is modified.
+                  EFI_NOT_FOUND  If table is not modified.
+
+**/
+EFI_STATUS
+EFIAPI
+AcpiTableAmlUpdate (
+  IN OUT  EFI_ACPI_SDT_HEADER  *NewTable
+  )
+{
+  UINT64  OemTableId;
+
+  if ((AsciiStrnCmp (NewTable->OemTableId, "AmdTable", 8) == 0)) {
+    DEBUG ((DEBUG_INFO, "Found (D/S)SDT table for patching OemTableId.\n"));
+    OemTableId = PcdGet64 (PcdAcpiDefaultOemTableId);
+    CopyMem (NewTable->OemTableId, &OemTableId, 8);
+    return EFI_SUCCESS;
+  }
+
+  return EFI_NOT_FOUND;
+}
+
+/**
+  Reserve Legacy VGA IO space.
+
+  @retval  EFI_SUCCESS  MMIO at Legacy VGA region has been allocated.
+  @retval  !EFI_SUCCESS Error allocating the legacy VGA region.
+
+**/
+EFI_STATUS
+EFIAPI
+ReserveLegacyVgaIoSpace (
+  VOID
+  )
+{
+  EFI_STATUS            Status;
+  EFI_PHYSICAL_ADDRESS  VgaMemAddress;
+
+  VgaMemAddress = (EFI_PHYSICAL_ADDRESS)VGA_MEM_BASE;
+  Status        = gBS->AllocatePages (
+                         AllocateAddress,
+                         EfiMemoryMappedIO,
+                         EFI_SIZE_TO_PAGES (VGA_MEM_SIZE),
+                         &VgaMemAddress
+                         );
+  return Status;
+}
+
+/**
+  Helper function to get size of MMIO region required for the Bus Range
+  configured.
+
+  @param[in]    BusRange      Chipset representation of Bus Range
+
+  @retval                     Size of MMIO required for bus range
+**/
+UINT64
+DecodeMmioBusRange (
+  UINT64  BusRange
+  )
+{
+  // Minimum MMIO region required is 1MB (1 Segment - 1 Bus).
+  // Set Mmio Size to 1MB.
+  UINT64  MmioSize;
+
+  MmioSize = 0x100000;
+
+  if (BusRange > 0x0E) {
+    MmioSize = SIZE_32GB;
+  } else {
+    MmioSize = (MmioSize << BusRange);
+  }
+
+  return MmioSize;
+}
+
+/**
+  Reserve PCIe Extended Config Space MMIO in the GCD and mark it runtime
+
+  @param[in]  ImageHandle  ImageHandle of the loaded driver.
+  @param[in]  SystemTable  Pointer to the EFI System Table.
+
+  @retval  EFI_SUCCESS  One or more of the drivers returned a success code.
+  @retval  !EFI_SUCCESS  Error initializing the Legacy PIC.
+
+**/
+EFI_STATUS
+EFIAPI
+ReservePcieExtendedConfigSpace (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  EFI_STATUS        Status;
+  AMD_MMIO_CFG_MSR  MmioCfgMsr;
+  UINT64            MmioCfgBase;
+  UINT64            MmioCfgSize;
+
+  Status = EFI_SUCCESS;
+  //
+  // Reserve MMIO for PCI-Config space
+  //
+  MmioCfgMsr.AsUint64 = AsmReadMsr64 (AMD_MMIO_CFG_MSR_ADDR);
+  MmioCfgBase         = MmioCfgMsr.AsUint64 & AMD_MMIO_CFG_ADDR_MASK;
+  MmioCfgSize         = DecodeMmioBusRange (MmioCfgMsr.AsBits.BusRange);
+  DEBUG ((DEBUG_INFO, "\nMMIO_CFG MSR = 0x%08lX\n", MmioCfgMsr.AsUint64));
+  DEBUG ((DEBUG_INFO, "  Enable = %d\n", MmioCfgMsr.AsBits.Enable));
+  DEBUG ((DEBUG_INFO, "  BusRange = %d\n", MmioCfgMsr.AsBits.BusRange));
+  DEBUG ((DEBUG_INFO, "  MmioCfgBase = 0x%08lX\n", MmioCfgBase));
+  DEBUG ((DEBUG_INFO, "  MmioCfgSize = 0x%08lX\n", MmioCfgSize));
+
+  if (MmioCfgMsr.AsBits.Enable) {
+    // Free Memory if it is allocated (call will likely return Not Found)
+    Status = gDS->FreeMemorySpace (
+                    MmioCfgBase,
+                    MmioCfgSize
+                    );
+    // Remove Memory Space from GCD map (could return Not Found)
+    Status = gDS->RemoveMemorySpace (
+                    MmioCfgBase,
+                    MmioCfgSize
+                    );
+    // Make sure Adding memory space succeeds or assert
+    Status = gDS->AddMemorySpace (
+                    EfiGcdMemoryTypeReserved,
+                    MmioCfgBase,
+                    MmioCfgSize,
+                    EFI_MEMORY_RUNTIME | EFI_MEMORY_UC
+                    );
+    ASSERT_EFI_ERROR (Status);
+    // Make sure Allocating memory space succeed or assert
+    Status = gDS->AllocateMemorySpace (
+                    EfiGcdAllocateAddress,
+                    EfiGcdMemoryTypeReserved,
+                    0,
+                    MmioCfgSize,
+                    &MmioCfgBase,
+                    ImageHandle,
+                    NULL
+                    );
+    ASSERT_EFI_ERROR (Status);
+
+    DEBUG ((
+      DEBUG_INFO,
+      "\nReserved PciCfg MMIO: Base = 0x%lX, Size = 0x%lX\n",
+      MmioCfgBase,
+      MmioCfgSize
+      ));
+  }
+
+  return Status;
+}
diff --git a/Platform/AMD/AmdMinBoardPkg/Library/DxeBoardInitLib/DxeBoardInitLibInternal.h b/Platform/AMD/AmdMinBoardPkg/Library/DxeBoardInitLib/DxeBoardInitLibInternal.h
new file mode 100644
index 0000000000..037328a34c
--- /dev/null
+++ b/Platform/AMD/AmdMinBoardPkg/Library/DxeBoardInitLib/DxeBoardInitLibInternal.h
@@ -0,0 +1,159 @@
+/** @file
+
+Copyright (C) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserved
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef DXE_BOARD_INIT_LIB_INTERNAL_H_
+#define DXE_BOARD_INIT_LIB_INTERNAL_H_
+
+#include <Uefi/UefiBaseType.h>
+#include <Register/Intel/Cpuid.h>
+#include <Protocol/AcpiSystemDescriptionTable.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Protocol/AcpiTable.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <IndustryStandard/Acpi65.h>
+#include <Library/SortLib.h>
+#include <Library/IoLib.h>
+#include <Register/IoApic.h>
+#include <Protocol/MpService.h>
+#include <Library/BaseLib.h>
+
+// Define temp buffer length for save IoApic data
+#define MAX_IOAPIC_NUM  0x20
+
+#define VGA_MEM_BASE  0xA0000
+#define VGA_MEM_SIZE  0x20000
+
+//
+// 48-bit MMIO space (MB-aligned)
+//
+#define AMD_MMIO_CFG_MSR_ADDR   0xC0010058UL
+#define AMD_MMIO_CFG_ADDR_MASK  0xFFFFFFF00000ULL
+
+typedef struct {
+  UINT8    Type;
+  UINT8    Length;
+} STRUCTURE_HEADER;
+
+#pragma pack(1)
+typedef union {
+  struct {
+    // HACK-HACK: Use UINT32 to keep compiler from using SHIFT intrinsics on NOOPT build
+    UINT32    Enable          : 1;    // [0]
+    UINT32    Reserved1       : 1;    // [1]
+    UINT32    BusRange        : 4;    // [5:2]
+    UINT32    Reserved2       : 14;   // [19:6]
+    UINT32    MmioCfgBaseAddr : 28;   // [47:20]
+    UINT32    Reserved3       : 16;   // [63:48]
+  } AsBits;
+
+  UINT64    AsUint64;
+} AMD_MMIO_CFG_MSR;
+#pragma pack()
+
+/**
+  Reserve PCIe Extended Config Space MMIO in the GCD and mark it runtime
+
+  @param[in]  ImageHandle  ImageHandle of the loaded driver.
+  @param[in]  SystemTable  Pointer to the EFI System Table.
+
+  @retval  EFI_SUCCESS  One or more of the drivers returned a success code.
+  @retval  !EFI_SUCCESS  Error initializing the Legacy PIC.
+**/
+EFI_STATUS
+EFIAPI
+ReservePcieExtendedConfigSpace (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  );
+
+/**
+  Prototype for callback function to patch ACPI table.
+
+  @param[in, out] NewTable            The pointer to ACPI table.
+  @return         EFI_SUCCESS         Always return EFI_SUCCESS
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PATCH_ACPITABLE)(
+  IN OUT  EFI_ACPI_SDT_HEADER  *NewTable
+  );
+
+/**
+  A helper function to update and re-install ACPI table.
+  It search for ACPI table for provided table signature,
+  if found then creates a copy of the table and invokes
+  the call back function.
+
+  @param[in] Signature           ACPI table signature
+  @param[in] CallbackFunction    The function to call to patch the searching ACPI table.
+
+  @return EFI_SUCCESS            Successfully Re-install the ACPI Table
+  @return EFI_NOT_FOUND          Table not found
+  @return EFI_STATUS             returns non-EFI_SUCCESS value in case of failure
+
+**/
+EFI_STATUS
+EFIAPI
+UpdateReinstallAcpiTable (
+  IN UINT32           Signature,
+  IN PATCH_ACPITABLE  CallbackFunction
+  );
+
+/**
+  A Callback function to patch the ACPI FADT table.
+  Updates FADT table with AMD specific values, which
+  are different than MinPlatformPkg.
+
+  @param[in, out] NewTable       Pointer to ACPI FADT table
+
+  @return         EFI_SUCCESS    Always return EFI_SUCCESSe
+
+**/
+EFI_STATUS
+EFIAPI
+FadtAcpiTablePatch (
+  IN OUT  EFI_ACPI_SDT_HEADER  *NewTable
+  );
+
+EFI_STATUS
+EFIAPI
+MadtAcpiTablePatch (
+  IN OUT  EFI_ACPI_SDT_HEADER  *NewTable
+  );
+
+/**
+  A Callback function to patch the ACPI DSDT/SSDT table.
+  Which has ASL code that needs to be updated.
+
+  @param[in, out] NewTable       Pointer to ACPI FADT table
+
+  @return         EFI_SUCCESS    Always return EFI_SUCCESSe
+
+**/
+EFI_STATUS
+EFIAPI
+AcpiTableAmlUpdate (
+  IN OUT  EFI_ACPI_SDT_HEADER  *NewTable
+  );
+
+/**
+  Reserve Legacy VGA IO space.
+
+  @retval  EFI_SUCCESS  MMIO at Legacy VGA region has been allocated.
+  @retval  !EFI_SUCCESS Error allocating the legacy VGA region.
+
+**/
+EFI_STATUS
+EFIAPI
+ReserveLegacyVgaIoSpace (
+  VOID
+  );
+
+#endif
diff --git a/Platform/AMD/AmdMinBoardPkg/Library/DxeBoardInitLib/MadtAcpiTablePatch.c b/Platform/AMD/AmdMinBoardPkg/Library/DxeBoardInitLib/MadtAcpiTablePatch.c
new file mode 100644
index 0000000000..aefb378981
--- /dev/null
+++ b/Platform/AMD/AmdMinBoardPkg/Library/DxeBoardInitLib/MadtAcpiTablePatch.c
@@ -0,0 +1,243 @@
+/** @file
+  This file patches the ACPI MADT table for AMD specific values.
+
+  Copyright (C) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserved
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "DxeBoardInitLibInternal.h"
+#include <Library/AmdPlatformSocLib.h>
+#include <Library/LocalApicLib.h>
+#define   AMD_CPUID_EXTENDED_TOPOLOGY_V2                 0x26
+#define   AMD_CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_CCX  0x03
+#define   AMD_CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_CCD  0x04
+#define   AMD_CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_DIE  0x05
+
+UINT32  mCcdOrder[16] = { 0, 4, 8, 12, 2, 6, 10, 14, 3, 7, 11, 15, 1, 5, 9, 13 };
+
+/**
+  Callback compare function.
+  Compares CCD number of provided arguments.
+
+  @param[in] LocalX2ApicLeft   Pointer to Left Buffer.
+  @param[in] LocalX2ApicRight  Pointer to Right Buffer.
+  @return    0                 If both are same
+             -1                If left value is less than righ value.
+             1                 If left value is greater than righ value.
+
+**/
+INTN
+EFIAPI
+SortByCcd (
+  CONST VOID  *LocalX2ApicLeft,
+  CONST VOID  *LocalX2ApicRight
+  )
+{
+  CONST EFI_ACPI_6_5_PROCESSOR_LOCAL_X2APIC_STRUCTURE  *Left;
+  CONST EFI_ACPI_6_5_PROCESSOR_LOCAL_X2APIC_STRUCTURE  *Right;
+  EFI_CPU_PHYSICAL_LOCATION2                           LeftLocation;
+  EFI_CPU_PHYSICAL_LOCATION2                           RightLocation;
+  UINT32                                               LeftCcdIndex;
+  UINT32                                               RightCcdIndex;
+  UINT32                                               Index;
+
+  Left  = (EFI_ACPI_6_5_PROCESSOR_LOCAL_X2APIC_STRUCTURE *)LocalX2ApicLeft;
+  Right = (EFI_ACPI_6_5_PROCESSOR_LOCAL_X2APIC_STRUCTURE *)LocalX2ApicRight;
+
+  GetProcessorLocation2ByApicId (
+    Left->X2ApicId,
+    &LeftLocation.Package,
+    &LeftLocation.Die,
+    &LeftLocation.Tile,
+    &LeftLocation.Module,
+    &LeftLocation.Core,
+    &LeftLocation.Thread
+    );
+
+  GetProcessorLocation2ByApicId (
+    Right->X2ApicId,
+    &RightLocation.Package,
+    &RightLocation.Die,
+    &RightLocation.Tile,
+    &RightLocation.Module,
+    &RightLocation.Core,
+    &RightLocation.Thread
+    );
+
+  // Get the CCD Index number
+  LeftCcdIndex = MAX_UINT32;
+  for (Index = 0; Index < ARRAY_SIZE (mCcdOrder); Index++) {
+    if (LeftLocation.Die == mCcdOrder[Index]) {
+      LeftCcdIndex = Index;
+      break;
+    }
+  }
+
+  RightCcdIndex = MAX_UINT32;
+  for (Index = 0; Index < ARRAY_SIZE (mCcdOrder); Index++) {
+    if (RightLocation.Die == mCcdOrder[Index]) {
+      RightCcdIndex = Index;
+      break;
+    }
+  }
+
+  // Now compare for quick sort
+  if (LeftCcdIndex < RightCcdIndex) {
+    return -1;
+  }
+
+  if (LeftCcdIndex > RightCcdIndex) {
+    return 1;
+  }
+
+  return 0;
+}
+
+/**
+  A Callback function to patch the ACPI MADT table.
+  Updates MADT table with AMD specific values, which
+  are different than MinPlatformPkg.
+
+  @param[in, out] NewTable       Pointer to ACPI MADT table
+
+  @return         EFI_SUCCESS    Always return EFI_SUCCESSe
+
+**/
+EFI_STATUS
+EFIAPI
+MadtAcpiTablePatch (
+  IN OUT  EFI_ACPI_SDT_HEADER  *NewTable
+  )
+{
+  UINT32                                               Index;
+  EFI_ACPI_6_5_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER  *NewMadtTable;
+  UINT8                                                *TablePtr;
+  UINT64                                               Length;
+  EFI_ACPI_6_5_IO_APIC_STRUCTURE                       *NbioIoApic;
+  UINT8                                                IoApicCount;
+  UINTN                                                LapicCount;
+  EFI_ACPI_6_5_PROCESSOR_LOCAL_X2APIC_STRUCTURE        *LocalX2ApicPtr;
+  EFI_ACPI_6_5_PROCESSOR_LOCAL_X2APIC_STRUCTURE        *SortedItem;
+  EFI_ACPI_6_5_PROCESSOR_LOCAL_X2APIC_STRUCTURE        *Src;
+  EFI_ACPI_6_5_PROCESSOR_LOCAL_X2APIC_STRUCTURE        *Dst;
+
+  // Patch the Table
+  NewMadtTable                  = (EFI_ACPI_6_5_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *)NewTable;
+  NewMadtTable->Header.Revision = 6;
+  // Get the IoApic information
+  NbioIoApic     = NULL;
+  IoApicCount    = 0;
+  LapicCount     = 0;
+  LocalX2ApicPtr = NULL;
+  GetIoApicInfo (&NbioIoApic, &IoApicCount);
+  if ((NbioIoApic == NULL) || (IoApicCount == 0)) {
+    DEBUG ((DEBUG_INFO, "%a:%d Cannot obtain NBIO IOAPIC information.\n", __FUNCTION__, __LINE__));
+    return EFI_SUCCESS;
+  }
+
+  // Create MADT header
+  TablePtr = (UINT8 *)NewMadtTable;
+  TablePtr = TablePtr + sizeof (EFI_ACPI_6_5_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER);
+  Length   = sizeof (EFI_ACPI_6_5_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER);
+
+  // Get the IOAPIC structure
+  Index = 0;    // now holds the IoApic Index
+  do {
+    if (((STRUCTURE_HEADER *)TablePtr)->Type == EFI_ACPI_6_5_IO_APIC) {
+      // Patch the IoApic Strucure
+      if (Index >= IoApicCount) {
+        /// Mark the extra IOAPIC structure Type as reserved, so that OSPM can ignore it.
+        /// As per ACPI specification 6.5 for MADT table
+        /// Subtype 0x18-0x7F are reserved, OSPM skips structures of the reserved type.
+        ((EFI_ACPI_6_5_IO_APIC_STRUCTURE *)TablePtr)->Type = 0x7F;
+      } else {
+        ((EFI_ACPI_6_5_IO_APIC_STRUCTURE *)TablePtr)->IoApicId                  = NbioIoApic[Index].IoApicId;
+        ((EFI_ACPI_6_5_IO_APIC_STRUCTURE *)TablePtr)->IoApicAddress             = NbioIoApic[Index].IoApicAddress;
+        ((EFI_ACPI_6_5_IO_APIC_STRUCTURE *)TablePtr)->GlobalSystemInterruptBase = NbioIoApic[Index].GlobalSystemInterruptBase;
+      }
+
+      Index++;
+    }
+
+    if (((STRUCTURE_HEADER *)TablePtr)->Type == EFI_ACPI_6_5_INTERRUPT_SOURCE_OVERRIDE) {
+      // Patch Flags
+      ((EFI_ACPI_6_5_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE *)TablePtr)->Flags = 0xF;
+    }
+
+    if (((STRUCTURE_HEADER *)TablePtr)->Type == EFI_ACPI_6_5_LOCAL_X2APIC_NMI) {
+      // Patch  Flags - Edge-triggered, Active High
+      ((EFI_ACPI_6_5_LOCAL_X2APIC_NMI_STRUCTURE *)TablePtr)->Flags = 0x0005;
+    }
+
+    if (((STRUCTURE_HEADER *)TablePtr)->Type == EFI_ACPI_6_5_PROCESSOR_LOCAL_X2APIC) {
+      if (LapicCount == 0) {
+        // Get the first entry pointer
+        LocalX2ApicPtr = (EFI_ACPI_6_5_PROCESSOR_LOCAL_X2APIC_STRUCTURE *)TablePtr;
+      }
+
+      LapicCount += 1;
+    }
+
+    Length   += ((STRUCTURE_HEADER *)TablePtr)->Length;
+    TablePtr += ((STRUCTURE_HEADER *)TablePtr)->Length;
+  } while (Length < NewMadtTable->Header.Length);
+
+  FreePool (NbioIoApic);
+
+  if (LocalX2ApicPtr != NULL) {
+    if (FixedPcdGet32 (PcdMaxCpuSocketCount) > 1) {
+      /// Sort by CCD location
+      PerformQuickSort (LocalX2ApicPtr, LapicCount/2, sizeof (EFI_ACPI_6_5_PROCESSOR_LOCAL_X2APIC_STRUCTURE), SortByCcd);
+      PerformQuickSort (LocalX2ApicPtr+(LapicCount/2), LapicCount/2, sizeof (EFI_ACPI_6_5_PROCESSOR_LOCAL_X2APIC_STRUCTURE), SortByCcd);
+    } else {
+      /// Sort by CCD location
+      PerformQuickSort (LocalX2ApicPtr, LapicCount, sizeof (EFI_ACPI_6_5_PROCESSOR_LOCAL_X2APIC_STRUCTURE), SortByCcd);
+    }
+
+    /// Now allocate the Uid
+    SortedItem = LocalX2ApicPtr;
+    for (Index = 0; Index < LapicCount; Index++, SortedItem++) {
+      SortedItem->AcpiProcessorUid = Index;
+    }
+
+    // Now separate the second thread list
+    SortedItem = LocalX2ApicPtr + 1;
+    if ((SortedItem->X2ApicId & 0x1) == 0x1) {
+      // It has multi-thread on
+      SortedItem = NULL;
+      SortedItem = AllocateZeroPool (sizeof (EFI_ACPI_6_5_PROCESSOR_LOCAL_X2APIC_STRUCTURE) * LapicCount);
+      if (SortedItem == NULL) {
+        return EFI_OUT_OF_RESOURCES;
+      }
+
+      Src = LocalX2ApicPtr;
+      Dst = SortedItem;
+      for (Index = 0; Index < LapicCount; Index++) {
+        if ((Src->X2ApicId & 0x1) == 0) {
+          CopyMem (Dst, Src, sizeof (EFI_ACPI_6_5_PROCESSOR_LOCAL_X2APIC_STRUCTURE));
+          Src++;
+          Dst++;
+        } else {
+          Src++;
+        }
+      }
+
+      Src = LocalX2ApicPtr;
+      for (Index = 0; Index < LapicCount; Index++) {
+        if ((Src->X2ApicId & 0x1) == 1) {
+          CopyMem (Dst, Src, sizeof (EFI_ACPI_6_5_PROCESSOR_LOCAL_X2APIC_STRUCTURE));
+          Src++;
+          Dst++;
+        } else {
+          Src++;
+        }
+      }
+
+      CopyMem (LocalX2ApicPtr, SortedItem, sizeof (EFI_ACPI_6_5_PROCESSOR_LOCAL_X2APIC_STRUCTURE) * LapicCount);
+      FreePool (SortedItem);
+    }
+  }
+
+  return EFI_SUCCESS;
+}
-- 
2.34.1



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



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [edk2-devel] [PATCH 5/5] AmdMinBoardPkg: Implements BoardBdsHookLib library
  2024-05-17  3:49 [edk2-devel] [PATCH 0/5] AmdMinBoardPkg: AMD board specific modules Abdul Lateef Attar via groups.io
                   ` (3 preceding siblings ...)
  2024-05-17  3:49 ` [edk2-devel] [PATCH 4/5] AmdMinBoardPkg: Implement BoardInitLib for DXE phase Abdul Lateef Attar via groups.io
@ 2024-05-17  3:49 ` Abdul Lateef Attar via groups.io
  2024-05-17  5:53 ` [edk2-devel] [PATCH 0/5] AmdMinBoardPkg: AMD board specific modules Chang, Abner via groups.io
  5 siblings, 0 replies; 7+ messages in thread
From: Abdul Lateef Attar via groups.io @ 2024-05-17  3:49 UTC (permalink / raw)
  To: devel; +Cc: Abdul Lateef Attar, Abner Chang, Paul Grimes

Implements BoardBdsHookLib library class for AMD platforms.

Cc: Abner Chang <abner.chang@amd.com>
Cc: Paul Grimes <paul.grimes@amd.com>
Signed-off-by: Abdul Lateef Attar <AbdulLateef.Attar@amd.com>
---
 .../AMD/AmdMinBoardPkg/AmdMinBoardPkg.dec     |   10 +
 .../AMD/AmdMinBoardPkg/AmdMinBoardPkg.dsc     |    2 +
 .../Include/Library/AmdBoardBdsHookLib.h      |  130 ++
 .../Library/BoardBdsHookLib/BoardBdsHook.h    |  242 +++
 .../Library/BoardBdsHookLib/BoardBdsHookLib.c | 1712 +++++++++++++++++
 .../BoardBdsHookLib/BoardBdsHookLib.inf       |  105 +
 .../Library/BoardBdsHookLib/BoardBootOption.c |  754 ++++++++
 .../Library/BoardBdsHookLib/BoardMemoryTest.c |   83 +
 8 files changed, 3038 insertions(+)
 create mode 100644 Platform/AMD/AmdMinBoardPkg/Include/Library/AmdBoardBdsHookLib.h
 create mode 100644 Platform/AMD/AmdMinBoardPkg/Library/BoardBdsHookLib/BoardBdsHook.h
 create mode 100644 Platform/AMD/AmdMinBoardPkg/Library/BoardBdsHookLib/BoardBdsHookLib.c
 create mode 100644 Platform/AMD/AmdMinBoardPkg/Library/BoardBdsHookLib/BoardBdsHookLib.inf
 create mode 100644 Platform/AMD/AmdMinBoardPkg/Library/BoardBdsHookLib/BoardBootOption.c
 create mode 100644 Platform/AMD/AmdMinBoardPkg/Library/BoardBdsHookLib/BoardMemoryTest.c

diff --git a/Platform/AMD/AmdMinBoardPkg/AmdMinBoardPkg.dec b/Platform/AMD/AmdMinBoardPkg/AmdMinBoardPkg.dec
index 03d1d77c34..47ec5b4b56 100644
--- a/Platform/AMD/AmdMinBoardPkg/AmdMinBoardPkg.dec
+++ b/Platform/AMD/AmdMinBoardPkg/AmdMinBoardPkg.dec
@@ -17,9 +17,19 @@
   PACKAGE_GUID                   = 44F9D761-9ECB-43DD-A5AC-177E5048701B
   PACKAGE_VERSION                = 0.1
 
+[Includes]
+  Include
+
 [Guids]
   gAmdMinBoardPkgTokenSpaceGuid  = {0xd4d23d79, 0x73bf, 0x460a, {0xa1, 0xc7, 0x85, 0xa3, 0xca, 0x71, 0xb9, 0x4c}}
 
+[LibraryClasses]
+  ##  @libraryclass    Provide services to platform BDS hook.
+  BoardBdsHookLib|Include/Library/AmdBoardBdsHookLib.h
+
+[Protocols]
+  gAmdBoardBdsBootOptionPriorityProtocolGuid = { 0x5806db97, 0x5303, 0x409f, { 0x8f, 0x09, 0xab, 0x29, 0xd8, 0x07, 0xa3, 0xf1}}
+
 [PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx]
   #
   # PCI HotPlug Resource Padding
diff --git a/Platform/AMD/AmdMinBoardPkg/AmdMinBoardPkg.dsc b/Platform/AMD/AmdMinBoardPkg/AmdMinBoardPkg.dsc
index e0afe1e755..e002e78f21 100644
--- a/Platform/AMD/AmdMinBoardPkg/AmdMinBoardPkg.dsc
+++ b/Platform/AMD/AmdMinBoardPkg/AmdMinBoardPkg.dsc
@@ -41,6 +41,7 @@
   BoardInitLib|AmdMinBoardPkg/Library/PeiBoardInitPreMemLib/PeiBoardInitPreMemLib.inf
 
 [LibraryClasses.common.DXE_DRIVER]
+  BoardBdsHookLib|AmdMinBoardPkg/Library/BoardBdsHookLib/BoardBdsHookLib.inf
   BoardInitLib|AmdMinBoardPkg/Library/DxeBoardInitLib/DxeBoardInitLib.inf
 
 [Components]
@@ -53,4 +54,5 @@
 
 [Components.X64]
   AmdMinBoardPkg/Library/DxeBoardInitLib/DxeBoardInitLib.inf
+  AmdMinBoardPkg/Library/BoardBdsHookLib/BoardBdsHookLib.inf
   AmdMinBoardPkg/PciHotPlug/PciHotPlugInit.inf
\ No newline at end of file
diff --git a/Platform/AMD/AmdMinBoardPkg/Include/Library/AmdBoardBdsHookLib.h b/Platform/AMD/AmdMinBoardPkg/Include/Library/AmdBoardBdsHookLib.h
new file mode 100644
index 0000000000..6bfa4747e0
--- /dev/null
+++ b/Platform/AMD/AmdMinBoardPkg/Include/Library/AmdBoardBdsHookLib.h
@@ -0,0 +1,130 @@
+/** @file
+  Header file for BDS Hook Library
+
+  Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef AMD_BOARD_BDS_HOOK_LIB_H_
+#define AMD_BOARD_BDS_HOOK_LIB_H_
+
+#include <Library/UefiLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/PlatformBootManagerLib.h>
+#include <Library/SortLib.h>
+
+#define AMD_BOARD_BDS_BOOT_OPTION_PRIORITY_PROTOCOL_GUID    \
+  { 0x5806db97, 0x5303, 0x409f,                         \
+    { 0x8f, 0x09, 0xab, 0x29, 0xd8, 0x07, 0xa3, 0xf1 }}
+
+/*
+  This protocol is introduced so the platform can give certain boot options
+  a custom priority value. Useful in boot overrides, or when IPMI doesn't inherently
+  support a specific boot override needed by the platform.
+*/
+struct _AMD_BOARD_BDS_BOOT_OPTION_PRIORITY_PROTOCOL {
+  UINT8           IpmiBootDeviceSelectorType;
+  SORT_COMPARE    Compare;
+};
+
+typedef struct _AMD_BOARD_BDS_BOOT_OPTION_PRIORITY_PROTOCOL AMD_BOARD_BDS_BOOT_OPTION_PRIORITY_PROTOCOL;
+
+extern EFI_GUID  gAmdBoardBdsBootOptionPriorityProtocolGuid;
+
+/**
+  Returns the boot option type of a device
+
+  @param[in] DevicePath         The path of device whose boot option type
+                                should be returned
+  @retval -1                    Device type not found
+  @retval > -1                  Device type found
+**/
+UINT8
+BootOptionType (
+  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath
+  );
+
+/**
+  This is the callback function for Bds Ready To Boot event.
+
+  @param[in]  Event   Pointer to this event
+  @param[in]  Context Event handler private data
+
+  @retval None.
+**/
+VOID
+EFIAPI
+BdsReadyToBootCallback (
+  IN  EFI_EVENT  Event,
+  IN  VOID       *Context
+  );
+
+/**
+  This is the callback function for Smm Ready To Lock event.
+
+  @param[in] Event      The Event this notify function registered to.
+  @param[in] Context    Pointer to the context data registered to the Event.
+**/
+VOID
+EFIAPI
+BdsSmmReadyToLockCallback (
+  IN EFI_EVENT  Event,
+  IN VOID       *Context
+  );
+
+/**
+  This is the callback function for PCI ENUMERATION COMPLETE.
+
+  @param[in] Event      The Event this notify function registered to.
+  @param[in] Context    Pointer to the context data registered to the Event.
+**/
+VOID
+EFIAPI
+BdsPciEnumCompleteCallback (
+  IN EFI_EVENT  Event,
+  IN VOID       *Context
+  );
+
+/**
+  Before console after trusted console event callback
+
+  @param[in] Event      The Event this notify function registered to.
+  @param[in] Context    Pointer to the context data registered to the Event.
+**/
+VOID
+EFIAPI
+BdsBeforeConsoleAfterTrustedConsoleCallback (
+  IN EFI_EVENT  Event,
+  IN VOID       *Context
+  );
+
+/**
+  Before console before end of DXE event callback
+
+  @param[in] Event      The Event this notify function registered to.
+  @param[in] Context    Pointer to the context data registered to the Event.
+**/
+VOID
+EFIAPI
+BdsBeforeConsoleBeforeEndOfDxeGuidCallback (
+  IN EFI_EVENT  Event,
+  IN VOID       *Context
+  );
+
+/**
+  After console ready before boot option event callback
+
+  @param[in] Event      The Event this notify function registered to.
+  @param[in] Context    Pointer to the context data registered to the Event.
+**/
+VOID
+EFIAPI
+BdsAfterConsoleReadyBeforeBootOptionCallback (
+  IN EFI_EVENT  Event,
+  IN VOID       *Context
+  );
+
+#endif
diff --git a/Platform/AMD/AmdMinBoardPkg/Library/BoardBdsHookLib/BoardBdsHook.h b/Platform/AMD/AmdMinBoardPkg/Library/BoardBdsHookLib/BoardBdsHook.h
new file mode 100644
index 0000000000..5c950c4866
--- /dev/null
+++ b/Platform/AMD/AmdMinBoardPkg/Library/BoardBdsHookLib/BoardBdsHook.h
@@ -0,0 +1,242 @@
+/** @file
+  Header file for BDS Hook Library
+
+  Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef BOARD_BDS_HOOK_H_
+#define BOARD_BDS_HOOK_H_
+
+#include <PiDxe.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/SimpleNetwork.h>
+#include <Protocol/PciRootBridgeIo.h>
+#include <Protocol/LoadFile.h>
+#include <Protocol/PciIo.h>
+#include <Protocol/CpuIo2.h>
+#include <Protocol/LoadedImage.h>
+#include <Protocol/DiskInfo.h>
+#include <Protocol/GraphicsOutput.h>
+#include <Protocol/UgaDraw.h>
+#include <Protocol/GenericMemoryTest.h>
+#include <Protocol/DevicePathToText.h>
+#include <Protocol/FirmwareVolume2.h>
+#include <Protocol/SimpleFileSystem.h>
+
+#include <Guid/CapsuleVendor.h>
+#include <Guid/MemoryTypeInformation.h>
+#include <Guid/GlobalVariable.h>
+#include <Guid/MemoryOverwriteControl.h>
+#include <Guid/FileInfo.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/PcdLib.h>
+#include <Library/PlatformBootManagerLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/UefiLib.h>
+#include <Library/HobLib.h>
+#include <Library/DxeServicesLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/PrintLib.h>
+#include <Library/HiiLib.h>
+#include <Library/CapsuleLib.h>
+#include <Library/PerformanceLib.h>
+
+#include <IndustryStandard/Pci30.h>
+#include <IndustryStandard/PciCodeId.h>
+#include <Protocol/PciEnumerationComplete.h>
+
+///
+/// For boot order override.
+///
+#define IPMI_BOOT_OVERRIDE_VAR_NAME  L"IpmiBootOverride"
+#define IS_FIRST_BOOT_VAR_NAME       L"IsFirstBoot"
+#define UEFI_HARD_DRIVE_NAME         L"UEFI Hard Drive"
+
+///
+/// ConnectType
+///
+#define CONSOLE_OUT  0x00000001
+#define STD_ERROR    0x00000002
+#define CONSOLE_IN   0x00000004
+#define CONSOLE_ALL  (CONSOLE_OUT | CONSOLE_IN | STD_ERROR)
+#define END_ENTIRE_DEVICE_PATH \
+  { \
+    END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, { END_DEVICE_PATH_LENGTH, 0 } \
+  }
+
+extern EFI_GUID       gUefiShellFileGuid;
+extern EFI_BOOT_MODE  gBootMode;
+
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL    *DevicePath;
+  UINTN                       ConnectType;
+} BDS_CONSOLE_CONNECT_ENTRY;
+
+//
+// Platform Root Bridge
+//
+typedef struct {
+  ACPI_HID_DEVICE_PATH        PciRootBridge;
+  EFI_DEVICE_PATH_PROTOCOL    End;
+} PLATFORM_ROOT_BRIDGE_DEVICE_PATH;
+
+//
+// Below is the platform console device path
+//
+typedef struct {
+  ACPI_HID_DEVICE_PATH        PciRootBridge;
+  PCI_DEVICE_PATH             IsaBridge;
+  ACPI_HID_DEVICE_PATH        Keyboard;
+  EFI_DEVICE_PATH_PROTOCOL    End;
+} PLATFORM_KEYBOARD_DEVICE_PATH;
+
+typedef struct {
+  ACPI_HID_DEVICE_PATH        PciRootBridge;
+  PCI_DEVICE_PATH             PciDevice;
+  EFI_DEVICE_PATH_PROTOCOL    End;
+} PLATFORM_ONBOARD_CONTROLLER_DEVICE_PATH;
+
+typedef struct {
+  ACPI_HID_DEVICE_PATH        PciRootBridge;
+  PCI_DEVICE_PATH             Pci0Device;
+  EFI_DEVICE_PATH_PROTOCOL    End;
+} PLATFORM_PEG_ROOT_CONTROLLER_DEVICE_PATH;
+
+typedef struct {
+  ACPI_HID_DEVICE_PATH        PciRootBridge;
+  PCI_DEVICE_PATH             PciBridge;
+  PCI_DEVICE_PATH             PciDevice;
+  EFI_DEVICE_PATH_PROTOCOL    End;
+} PLATFORM_PCI_CONTROLLER_DEVICE_PATH;
+
+//
+// Below is the boot option device path
+//
+
+#define CLASS_HID          3
+#define SUBCLASS_BOOT      1
+#define PROTOCOL_KEYBOARD  1
+
+typedef struct {
+  USB_CLASS_DEVICE_PATH       UsbClass;
+  EFI_DEVICE_PATH_PROTOCOL    End;
+} USB_CLASS_FORMAT_DEVICE_PATH;
+
+extern USB_CLASS_FORMAT_DEVICE_PATH  gUsbClassKeyboardDevicePath;
+
+//
+// Platform BDS Functions
+//
+
+/**
+  Perform the memory test base on the memory test intensive level,
+  and update the memory resource.
+
+  @param[in]  Level         The memory test intensive level.
+
+  @retval EFI_STATUS    Success test all the system memory and update
+                        the memory resource
+
+**/
+EFI_STATUS
+MemoryTest (
+  IN EXTENDMEM_COVERAGE_LEVEL  Level
+  );
+
+/**
+  Connect with predeined platform connect sequence,
+  the OEM/IBV can customize with their own connect sequence.
+
+  @param[in] BootMode          Boot mode of this boot.
+**/
+VOID
+ConnectSequence (
+  IN EFI_BOOT_MODE  BootMode
+  );
+
+/**
+   Compares boot priorities of two boot options
+
+  @param[in] Left       The left boot option
+  @param[in] Right      The right boot option
+
+  @return           The difference between the Left and Right
+                    boot options
+ **/
+INTN
+EFIAPI
+CompareBootOption (
+  IN CONST VOID  *Left,
+  IN CONST VOID  *Right
+  );
+
+/**
+   Compares boot priorities of two boot options, while giving PXE the highest priority
+
+  @param[in] Left       The left boot option
+  @param[in] Right      The right boot option
+
+  @return           The difference between the Left and Right
+                    boot options
+**/
+INTN
+EFIAPI
+CompareBootOptionPxePriority (
+  IN CONST VOID  *Left,
+  IN CONST VOID  *Right
+  );
+
+/**
+   Compares boot priorities of two boot options, while giving HDD the highest priority
+
+  @param[in] Left       The left boot option
+  @param[in] Right      The right boot option
+
+  @return           The difference between the Left and Right
+                    boot options
+**/
+INTN
+EFIAPI
+CompareBootOptionHddPriority (
+  IN CONST VOID  *Left,
+  IN CONST VOID  *Right
+  );
+
+/**
+  This function is called after all the boot options are enumerated and ordered properly.
+**/
+VOID
+RegisterStaticHotkey (
+  VOID
+  );
+
+/**
+  Registers/Unregisters boot option hotkey
+**/
+VOID
+RegisterDefaultBootOption (
+  VOID
+  );
+
+/**
+  Add console variable device paths
+
+  @param[in] ConsoleType         ConIn or ConOut
+  @param[in] ConsoleDevicePath   Device path to be added
+**/
+VOID
+AddConsoleVariable (
+  IN CONSOLE_TYPE     ConsoleType,
+  IN EFI_DEVICE_PATH  *ConsoleDevicePath
+  );
+
+#endif //BOARD_BDS_HOOK_H_
diff --git a/Platform/AMD/AmdMinBoardPkg/Library/BoardBdsHookLib/BoardBdsHookLib.c b/Platform/AMD/AmdMinBoardPkg/Library/BoardBdsHookLib/BoardBdsHookLib.c
new file mode 100644
index 0000000000..3d7c0c2bf7
--- /dev/null
+++ b/Platform/AMD/AmdMinBoardPkg/Library/BoardBdsHookLib/BoardBdsHookLib.c
@@ -0,0 +1,1712 @@
+/** @file
+  This library registers Bds callbacks. It is a default library
+  implementation instance of the BDS hook library
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  Copyright (C) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Guid/EventGroup.h>
+#include <Library/IoLib.h>
+#include <Library/PciLib.h>
+#include <Library/UefiBootManagerLib.h>
+#include <Library/Tcg2PhysicalPresenceLib.h>
+#include <Library/IpmiBaseLib.h>
+#include <Library/IpmiCommandLib.h>
+#include <Protocol/BlockIo.h>
+#include <Protocol/UsbIo.h>
+#include <Protocol/PciEnumerationComplete.h>
+#include <IndustryStandard/Ipmi.h>
+#include <Library/AmdBoardBdsHookLib.h>
+#include "BoardBdsHook.h"
+
+#ifdef INTERNAL_IDS
+  #include <Register/Amd/Msr.h>
+#endif
+
+CHAR16                                       *mConsoleVar[] = { L"ConIn", L"ConOut" };
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_BOOT_MODE  gBootMode;
+BOOLEAN                                      gPPRequireUIConfirm;
+extern UINTN                                 mBootMenuOptionNumber;
+
+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
+  },
+  END_ENTIRE_DEVICE_PATH
+};
+
+#ifdef INTERNAL_IDS
+EFI_STATUS
+PrintSocOpnInfo (
+  IN  VOID
+  );
+
+#endif
+
+//
+// BDS Platform Functions
+//
+
+/**
+  Checks if Mor bit is set.
+  @retval TRUE    The MOR bit is set
+  @retval FALSE   The MOR bit is not set
+**/
+BOOLEAN
+IsMorBitSet (
+  VOID
+  )
+{
+  UINTN       MorControl;
+  EFI_STATUS  Status;
+  UINTN       DataSize;
+
+  //
+  // Check if the MOR bit is set.
+  //
+  DataSize = sizeof (MorControl);
+  Status   = gRT->GetVariable (
+                    MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME,
+                    &gEfiMemoryOverwriteControlDataGuid,
+                    NULL,
+                    &DataSize,
+                    &MorControl
+                    );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_INFO, " gEfiMemoryOverwriteControlDataGuid doesn't exist!!***\n"));
+    MorControl = 0;
+  } else {
+    DEBUG ((DEBUG_INFO, " Get the gEfiMemoryOverwriteControlDataGuid = %x!!***\n", MorControl));
+  }
+
+  return (BOOLEAN)(MorControl & 0x01);
+}
+
+/**
+  Prints device paths.
+  @param[in] Name           The device name.
+  @param[in] DevicePath     The device path to be printed
+**/
+VOID
+EFIAPI
+DumpDevicePath (
+  IN CHAR16           *Name,
+  IN EFI_DEVICE_PATH  *DevicePath
+  )
+{
+  CHAR16  *Str;
+
+  Str = ConvertDevicePathToText (DevicePath, TRUE, TRUE);
+  DEBUG ((DEBUG_INFO, "%s: %s\n", Name, Str));
+  if (Str != NULL) {
+    FreePool (Str);
+  }
+}
+
+/**
+  Return whether the device is trusted console.
+
+  @param[in]  ConsoleType  The console type.
+  @param[in]  Device       The device path to be tested.
+
+  @retval     TRUE   The device can be trusted.
+  @retval     FALSE  The device cannot be trusted.
+**/
+BOOLEAN
+IsTrustedConsole (
+  IN CONSOLE_TYPE              ConsoleType,
+  IN EFI_DEVICE_PATH_PROTOCOL  *Device
+  )
+{
+  VOID                      *TrustedConsoleDevicepath;
+  EFI_DEVICE_PATH_PROTOCOL  *TempDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL  *Instance;
+  UINTN                     Size;
+  EFI_DEVICE_PATH_PROTOCOL  *ConsoleDevice;
+
+  if (Device == NULL) {
+    return FALSE;
+  }
+
+  ConsoleDevice = DuplicateDevicePath (Device);
+
+  TrustedConsoleDevicepath = NULL;
+
+  switch (ConsoleType) {
+    case ConIn:
+      TrustedConsoleDevicepath = DuplicateDevicePath (PcdGetPtr (PcdTrustedConsoleInputDevicePath));
+      break;
+    case ConOut:
+      //
+      // Check GOP and remove last node
+      //
+      TempDevicePath = ConsoleDevice;
+      while (!IsDevicePathEndType (TempDevicePath)) {
+        if ((DevicePathType (TempDevicePath) == ACPI_DEVICE_PATH) &&
+            (DevicePathSubType (TempDevicePath) == ACPI_ADR_DP))
+        {
+          SetDevicePathEndNode (TempDevicePath);
+          break;
+        }
+
+        TempDevicePath = NextDevicePathNode (TempDevicePath);
+      }
+
+      TrustedConsoleDevicepath = DuplicateDevicePath (PcdGetPtr (PcdTrustedConsoleOutputDevicePath));
+      break;
+    default:
+      ASSERT (FALSE);
+      break;
+  }
+
+  TempDevicePath = TrustedConsoleDevicepath;
+  do {
+    Instance = GetNextDevicePathInstance (&TempDevicePath, &Size);
+    if (Instance == NULL) {
+      break;
+    }
+
+    if (CompareMem (ConsoleDevice, Instance, Size - END_DEVICE_PATH_LENGTH) == 0) {
+      FreePool (Instance);
+      FreePool (ConsoleDevice);
+      if (TempDevicePath != NULL) {
+        FreePool (TempDevicePath);
+      }
+
+      return TRUE;
+    }
+
+    FreePool (Instance);
+  } while (TempDevicePath != NULL);
+
+  FreePool (ConsoleDevice);
+  if (TempDevicePath != NULL) {
+    FreePool (TempDevicePath);
+  }
+
+  return FALSE;
+}
+
+/**
+  Return whether the USB device path is in a short form.
+
+  @param[in] DevicePath  The device path to be tested.
+
+  @retval TRUE   The device path is in short form.
+  @retval FALSE  The device path is not in short form.
+**/
+BOOLEAN
+IsUsbShortForm (
+  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath
+  )
+{
+  if ((DevicePathType (DevicePath) == MESSAGING_DEVICE_PATH) &&
+      ((DevicePathSubType (DevicePath) == MSG_USB_CLASS_DP) ||
+       (DevicePathSubType (DevicePath) == MSG_USB_WWID_DP)))
+  {
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+/**
+  Connect the USB short form device path.
+
+  @param[in] DevicePath   USB short form device path
+
+  @retval EFI_SUCCESS           Successfully connected the USB device
+  @retval EFI_NOT_FOUND         Cannot connect the USB device
+  @retval EFI_INVALID_PARAMETER The device path is invalid.
+**/
+EFI_STATUS
+ConnectUsbShortFormDevicePath (
+  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath
+  )
+{
+  EFI_STATUS           Status;
+  EFI_HANDLE           *Handles;
+  UINTN                HandleCount;
+  UINTN                Index;
+  EFI_PCI_IO_PROTOCOL  *PciIo;
+  UINT8                Class[3];
+  BOOLEAN              AtLeastOneConnected;
+
+  //
+  // Check the passed in parameters
+  //
+  if (DevicePath == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (!IsUsbShortForm (DevicePath)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Find the usb host controller firstly, then connect with the remaining device path
+  //
+  AtLeastOneConnected = FALSE;
+  Status              = gBS->LocateHandleBuffer (
+                               ByProtocol,
+                               &gEfiPciIoProtocolGuid,
+                               NULL,
+                               &HandleCount,
+                               &Handles
+                               );
+  for (Index = 0; Index < HandleCount; Index++) {
+    Status = gBS->HandleProtocol (
+                    Handles[Index],
+                    &gEfiPciIoProtocolGuid,
+                    (VOID **)&PciIo
+                    );
+    if (!EFI_ERROR (Status)) {
+      //
+      // Check whether the Pci device is the wanted usb host controller
+      //
+      Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0x09, 3, &Class);
+      if (!EFI_ERROR (Status) &&
+          ((PCI_CLASS_SERIAL == Class[2]) && (PCI_CLASS_SERIAL_USB == Class[1])))
+      {
+        Status = gBS->ConnectController (
+                        Handles[Index],
+                        NULL,
+                        DevicePath,
+                        FALSE
+                        );
+        if (!EFI_ERROR (Status)) {
+          AtLeastOneConnected = TRUE;
+        }
+      }
+    }
+  }
+
+  return AtLeastOneConnected ? EFI_SUCCESS : EFI_NOT_FOUND;
+}
+
+/**
+  Return whether the Handle is a vga handle.
+
+  @param[in] Handle  The handle to be tested.
+
+  @retval TRUE   The handle is a vga handle.
+  @retval FALSE  The handle is not a vga handle..
+**/
+BOOLEAN
+IsVgaHandle (
+  IN EFI_HANDLE  Handle
+  )
+{
+  EFI_PCI_IO_PROTOCOL  *PciIo;
+  PCI_TYPE00           Pci;
+  EFI_STATUS           Status;
+
+  Status = gBS->HandleProtocol (
+                  Handle,
+                  &gEfiPciIoProtocolGuid,
+                  (VOID **)&PciIo
+                  );
+  if (!EFI_ERROR (Status)) {
+    Status = PciIo->Pci.Read (
+                          PciIo,
+                          EfiPciIoWidthUint32,
+                          0,
+                          sizeof (Pci) / sizeof (UINT32),
+                          &Pci
+                          );
+    if (!EFI_ERROR (Status)) {
+      if (IS_PCI_VGA (&Pci) || IS_PCI_OLD_VGA (&Pci)) {
+        return TRUE;
+      }
+    }
+  }
+
+  return FALSE;
+}
+
+/**
+  Return whether the device path points to a video controller.
+
+  @param[in] DevicePath  The device path to be tested.
+
+  @retval TRUE   The device path points to a video controller.
+  @retval FALSE  The device path does not point to a video controller.
+**/
+EFI_HANDLE
+IsVideoController (
+  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath
+  )
+{
+  EFI_DEVICE_PATH_PROTOCOL  *DupDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL  *TempDevicePath;
+  EFI_STATUS                Status;
+  EFI_HANDLE                DeviceHandle;
+
+  DupDevicePath = DuplicateDevicePath (DevicePath);
+  ASSERT (DupDevicePath != NULL);
+  if (DupDevicePath == NULL) {
+    return NULL;
+  }
+
+  TempDevicePath = DupDevicePath;
+  Status         = gBS->LocateDevicePath (
+                          &gEfiDevicePathProtocolGuid,
+                          &TempDevicePath,
+                          &DeviceHandle
+                          );
+  FreePool (DupDevicePath);
+  if (EFI_ERROR (Status)) {
+    return NULL;
+  }
+
+  if (IsVgaHandle (DeviceHandle)) {
+    return DeviceHandle;
+  } else {
+    return NULL;
+  }
+}
+
+/**
+  Return whether the device path is a GOP device path.
+
+  @param[in] DevicePath  The device path to be tested.
+
+  @retval TRUE   The device path is a GOP device path.
+  @retval FALSE  The device on the device path is not a GOP device path.
+**/
+BOOLEAN
+IsGopDevicePath (
+  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath
+  )
+{
+  while (!IsDevicePathEndType (DevicePath)) {
+    if ((DevicePathType (DevicePath) == ACPI_DEVICE_PATH) &&
+        (DevicePathSubType (DevicePath) == ACPI_ADR_DP))
+    {
+      return TRUE;
+    }
+
+    DevicePath = NextDevicePathNode (DevicePath);
+  }
+
+  return FALSE;
+}
+
+/**
+  Remove all GOP device path instance from DevicePath and add the Gop to the DevicePath.
+
+  @param[in] DevicePath  The device path to be removed
+  @param[in] Gop         The device path to be added.
+
+  @retval Return     The updated device path.
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+UpdateGopDevicePath (
+  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath,
+  IN EFI_DEVICE_PATH_PROTOCOL  *Gop
+  )
+{
+  UINTN                     Size;
+  UINTN                     GopSize;
+  EFI_DEVICE_PATH_PROTOCOL  *Temp;
+  EFI_DEVICE_PATH_PROTOCOL  *Return;
+  EFI_DEVICE_PATH_PROTOCOL  *Instance;
+  BOOLEAN                   Exist;
+
+  Exist   = FALSE;
+  Return  = NULL;
+  GopSize = GetDevicePathSize (Gop);
+  do {
+    Instance = GetNextDevicePathInstance (&DevicePath, &Size);
+    if (Instance == NULL) {
+      break;
+    }
+
+    if (!IsGopDevicePath (Instance) ||
+        ((Size == GopSize) && (CompareMem (Instance, Gop, GopSize) == 0))
+        )
+    {
+      if ((Size == GopSize) && (CompareMem (Instance, Gop, GopSize) == 0)) {
+        Exist = TRUE;
+      }
+
+      Temp   = Return;
+      Return = AppendDevicePathInstance (Return, Instance);
+      if (Temp != NULL) {
+        FreePool (Temp);
+      }
+    }
+
+    FreePool (Instance);
+  } while (DevicePath != NULL);
+
+  if (!Exist) {
+    Temp   = Return;
+    Return = AppendDevicePathInstance (Return, Gop);
+    if (Temp != NULL) {
+      FreePool (Temp);
+    }
+  }
+
+  return Return;
+}
+
+/**
+  Get Graphics Controller Handle. VgaDevices needs to be freed by caller.
+
+  @param[in] NeedTrustedConsole     The flag to determine if trusted console
+                                    or non trusted console should be returned
+  @param[out] VgaDevices            Array of handles corresponding to
+                                    valid VGA devices
+  @param[out] VgaDevicesCount       Number of VGA devices found and placed in
+                                    VgaDevices
+
+  @retval EFI ERROR                 No VGA capable devices found
+  @retval EFI_SUCCESS               At least one VGA device found
+**/
+EFI_STATUS
+EFIAPI
+GetGraphicsController (
+  IN  BOOLEAN     NeedTrustedConsole,
+  OUT EFI_HANDLE  **VgaDevices,
+  OUT UINTN       *VgaDevicesCount
+  )
+{
+  EFI_STATUS                Status;
+  UINTN                     Index;
+  EFI_HANDLE                *PciHandles;
+  UINTN                     PciHandlesSize;
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
+  UINT32                    NumDevices;
+
+  if ((VgaDevicesCount == NULL) || (VgaDevices == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  NumDevices = 0;
+  Status     = gBS->LocateHandleBuffer (
+                      ByProtocol,
+                      &gEfiPciIoProtocolGuid,
+                      NULL,
+                      &PciHandlesSize,
+                      &PciHandles
+                      );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  *VgaDevices = AllocateZeroPool (sizeof (EFI_HANDLE) * PciHandlesSize);
+  if (VgaDevices == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  for (Index = 0; Index < PciHandlesSize; Index++) {
+    Status = gBS->HandleProtocol (
+                    PciHandles[Index],
+                    &gEfiDevicePathProtocolGuid,
+                    (VOID **)&DevicePath
+                    );
+    if (EFI_ERROR (Status)) {
+      continue;
+    }
+
+    if (!IsVgaHandle (PciHandles[Index])) {
+      continue;
+    }
+
+    if ((NeedTrustedConsole && IsTrustedConsole (ConOut, DevicePath)) ||
+        ((!NeedTrustedConsole) && (!IsTrustedConsole (ConOut, DevicePath))))
+    {
+      VgaDevices[0][NumDevices] = PciHandles[Index];
+      NumDevices++;
+    }
+  }
+
+  *VgaDevicesCount = NumDevices;
+  if (NumDevices > 0) {
+    return EFI_SUCCESS;
+  } else {
+    return EFI_NOT_FOUND;
+  }
+}
+
+/**
+  Updates Graphic ConOut variable. This function searches for all VGA capable output devices and
+  adds them to the ConOut variable.
+
+  @param[in] NeedTrustedConsole    The flag that determines if trusted console
+  or non trusted console should be returned
+**/
+VOID
+UpdateGraphicConOut (
+  IN BOOLEAN  NeedTrustedConsole
+  )
+{
+  EFI_DEVICE_PATH_PROTOCOL  *GopDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL  *ConOutDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL  *UpdatedConOutDevicePath;
+  EFI_HANDLE                *VgaDevices;
+  UINTN                     VgaDevicesCount;
+  UINTN                     Count;
+  EFI_STATUS                Status;
+
+  Count           = 0;
+  VgaDevicesCount = 0;
+
+  //
+  // Update ConOut variable
+  //
+  Status = GetGraphicsController (NeedTrustedConsole, &VgaDevices, &VgaDevicesCount);
+  if (Status == EFI_SUCCESS) {
+    GetEfiGlobalVariable2 (L"ConOut", (VOID **)&ConOutDevicePath, NULL);
+    if (ConOutDevicePath != NULL) {
+      DumpDevicePath (L"Original ConOut variable", ConOutDevicePath);
+      FreePool (ConOutDevicePath);
+    }
+
+    // Add VGA devices to ConOut
+    for (Count = 0; Count < VgaDevicesCount; Count++) {
+      //
+      // Connect the GOP driver
+      //
+      gBS->ConnectController (VgaDevices[Count], NULL, NULL, TRUE);
+      //
+      // Get the GOP device path
+      // NOTE: We may get a device path that contains Controller node in it.
+      //
+      GopDevicePath = EfiBootManagerGetGopDevicePath (VgaDevices[Count]);
+      if (GopDevicePath != NULL) {
+        GetEfiGlobalVariable2 (L"ConOut", (VOID **)&ConOutDevicePath, NULL);
+        if (ConOutDevicePath != NULL) {
+          UpdatedConOutDevicePath = UpdateGopDevicePath (ConOutDevicePath, GopDevicePath);
+          if (UpdatedConOutDevicePath != NULL) {
+            gRT->SetVariable (
+                   L"ConOut",
+                   &gEfiGlobalVariableGuid,
+                   EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+                   GetDevicePathSize (UpdatedConOutDevicePath),
+                   UpdatedConOutDevicePath
+                   );
+            FreePool (UpdatedConOutDevicePath);
+          }
+
+          FreePool (ConOutDevicePath);
+        }
+
+        FreePool (GopDevicePath);
+      }
+    }
+
+    FreePool (VgaDevices);
+  }
+
+  GetEfiGlobalVariable2 (L"ConOut", (VOID **)&ConOutDevicePath, NULL);
+  if (ConOutDevicePath != NULL) {
+    DumpDevicePath (L"Final ConOut variable", ConOutDevicePath);
+    FreePool (ConOutDevicePath);
+  }
+}
+
+/**
+  The function connects the trusted consoles.
+**/
+VOID
+ConnectTrustedConsole (
+  VOID
+  )
+{
+  EFI_DEVICE_PATH_PROTOCOL  *Consoles;
+  EFI_DEVICE_PATH_PROTOCOL  *TempDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL  *Instance;
+  EFI_DEVICE_PATH_PROTOCOL  *Next;
+  UINTN                     Size;
+  UINTN                     Index;
+  EFI_HANDLE                Handle;
+  EFI_STATUS                Status;
+  VOID                      *TrustedConsoleDevicepath;
+
+  TrustedConsoleDevicepath = PcdGetPtr (PcdTrustedConsoleInputDevicePath);
+  DumpDevicePath (L"TrustedConsoleIn", TrustedConsoleDevicepath);
+  TrustedConsoleDevicepath = PcdGetPtr (PcdTrustedConsoleOutputDevicePath);
+  DumpDevicePath (L"TrustedConsoleOut", TrustedConsoleDevicepath);
+
+  for (Index = 0; Index < sizeof (mConsoleVar) / sizeof (mConsoleVar[0]); Index++) {
+    GetEfiGlobalVariable2 (mConsoleVar[Index], (VOID **)&Consoles, NULL);
+
+    TempDevicePath = Consoles;
+    do {
+      Instance = GetNextDevicePathInstance (&TempDevicePath, &Size);
+      if (Instance == NULL) {
+        break;
+      }
+
+      if (IsTrustedConsole (Index, Instance)) {
+        if (IsUsbShortForm (Instance)) {
+          ConnectUsbShortFormDevicePath (Instance);
+        } else {
+          for (Next = Instance; !IsDevicePathEnd (Next); Next = NextDevicePathNode (Next)) {
+            if ((DevicePathType (Next) == ACPI_DEVICE_PATH) && (DevicePathSubType (Next) == ACPI_ADR_DP)) {
+              break;
+            } else if ((DevicePathType (Next) == HARDWARE_DEVICE_PATH) &&
+                       (DevicePathSubType (Next) == HW_CONTROLLER_DP) &&
+                       (DevicePathType (NextDevicePathNode (Next)) == ACPI_DEVICE_PATH) &&
+                       (DevicePathSubType (NextDevicePathNode (Next)) == ACPI_ADR_DP)
+                       )
+            {
+              break;
+            }
+          }
+
+          if (!IsDevicePathEnd (Next)) {
+            SetDevicePathEndNode (Next);
+            Status = EfiBootManagerConnectDevicePath (Instance, &Handle);
+            if (!EFI_ERROR (Status)) {
+              gBS->ConnectController (Handle, NULL, NULL, TRUE);
+            }
+          } else {
+            EfiBootManagerConnectDevicePath (Instance, NULL);
+          }
+        }
+      }
+
+      FreePool (Instance);
+    } while (TempDevicePath != NULL);
+
+    if (Consoles != NULL) {
+      FreePool (Consoles);
+    }
+  }
+}
+
+/**
+  The function connects the trusted Storages.
+**/
+VOID
+ConnectTrustedStorage (
+  VOID
+  )
+{
+  VOID                      *TrustedStorageDevicepath;
+  EFI_DEVICE_PATH_PROTOCOL  *TempDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL  *Instance;
+  UINTN                     Size;
+  EFI_DEVICE_PATH_PROTOCOL  *TempStorageDevicePath;
+  EFI_STATUS                Status;
+  EFI_HANDLE                DeviceHandle;
+
+  TrustedStorageDevicepath = DuplicateDevicePath (PcdGetPtr (PcdTrustedStorageDevicePath));
+  DumpDevicePath (L"TrustedStorage", TrustedStorageDevicepath);
+
+  TempDevicePath = TrustedStorageDevicepath;
+  do {
+    Instance = GetNextDevicePathInstance (&TempDevicePath, &Size);
+    if (Instance == NULL) {
+      break;
+    }
+
+    EfiBootManagerConnectDevicePath (Instance, NULL);
+
+    TempStorageDevicePath = Instance;
+
+    Status = gBS->LocateDevicePath (
+                    &gEfiDevicePathProtocolGuid,
+                    &TempStorageDevicePath,
+                    &DeviceHandle
+                    );
+    if (!EFI_ERROR (Status)) {
+      gBS->ConnectController (DeviceHandle, NULL, NULL, FALSE);
+    }
+
+    FreePool (Instance);
+  } while (TempDevicePath != NULL);
+
+  if (TempDevicePath != NULL) {
+    FreePool (TempDevicePath);
+  }
+}
+
+/**
+  Check if current BootCurrent variable is internal shell boot option.
+
+  @retval  TRUE         BootCurrent is internal shell.
+  @retval  FALSE        BootCurrent is not internal shell.
+**/
+BOOLEAN
+BootCurrentIsInternalShell (
+  VOID
+  )
+{
+  UINTN                     VarSize;
+  UINT16                    BootCurrent;
+  CHAR16                    BootOptionName[16];
+  UINT8                     *BootOption;
+  UINT8                     *Ptr;
+  BOOLEAN                   Result;
+  EFI_STATUS                Status;
+  EFI_DEVICE_PATH_PROTOCOL  *TempDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL  *LastDeviceNode;
+  EFI_GUID                  *GuidPoint;
+
+  BootOption = NULL;
+  Result     = FALSE;
+
+  //
+  // Get BootCurrent variable
+  //
+  VarSize = sizeof (UINT16);
+  Status  = gRT->GetVariable (
+                   L"BootCurrent",
+                   &gEfiGlobalVariableGuid,
+                   NULL,
+                   &VarSize,
+                   &BootCurrent
+                   );
+  if (EFI_ERROR (Status)) {
+    return FALSE;
+  }
+
+  //
+  // Create boot option Bootxxxx from BootCurrent
+  //
+  UnicodeSPrint (BootOptionName, sizeof (BootOptionName), L"Boot%04X", BootCurrent);
+
+  GetEfiGlobalVariable2 (BootOptionName, (VOID **)&BootOption, &VarSize);
+  if ((BootOption == NULL) || (VarSize == 0)) {
+    return FALSE;
+  }
+
+  Ptr            = BootOption;
+  Ptr           += sizeof (UINT32);
+  Ptr           += sizeof (UINT16);
+  Ptr           += StrSize ((CHAR16 *)Ptr);
+  TempDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)Ptr;
+  LastDeviceNode = TempDevicePath;
+  while (!IsDevicePathEnd (TempDevicePath)) {
+    LastDeviceNode = TempDevicePath;
+    TempDevicePath = NextDevicePathNode (TempDevicePath);
+  }
+
+  GuidPoint = EfiGetNameGuidFromFwVolDevicePathNode (
+                (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)LastDeviceNode
+                );
+  if ((GuidPoint != NULL) &&
+      ((CompareGuid (GuidPoint, &gUefiShellFileGuid))))
+  {
+    //
+    // if this option is internal shell, return TRUE
+    //
+    Result = TRUE;
+  }
+
+  if (BootOption != NULL) {
+    FreePool (BootOption);
+    BootOption = NULL;
+  }
+
+  return Result;
+}
+
+/**
+  This function will change video resolution and text mode
+  for internal shell when internal shell is launched.
+
+  @param   None.
+
+  @retval  EFI_SUCCESS  Mode is changed successfully.
+  @retval  Others       Mode failed to changed.
+**/
+EFI_STATUS
+EFIAPI
+ChangeModeForInternalShell (
+  VOID
+  )
+{
+  EFI_GRAPHICS_OUTPUT_PROTOCOL          *GraphicsOutput;
+  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL       *SimpleTextOut;
+  UINTN                                 SizeOfInfo;
+  EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  *Info;
+  UINT32                                MaxGopMode;
+  UINT32                                MaxTextMode;
+  UINT32                                ModeNumber;
+  UINTN                                 HandleCount;
+  EFI_HANDLE                            *HandleBuffer;
+  EFI_STATUS                            Status;
+  UINTN                                 Index;
+  UINTN                                 CurrentColumn;
+  UINTN                                 CurrentRow;
+
+  //
+  // Internal shell mode
+  //
+  UINT32  mShellModeColumn;
+  UINT32  mShellModeRow;
+  UINT32  mShellHorizontalResolution;
+  UINT32  mShellVerticalResolution;
+
+  //
+  // Get user defined text mode for internal shell only once.
+  //
+  mShellHorizontalResolution = PcdGet32 (PcdSetupVideoHorizontalResolution);
+  mShellVerticalResolution   = PcdGet32 (PcdSetupVideoVerticalResolution);
+  mShellModeColumn           = PcdGet32 (PcdSetupConOutColumn);
+  mShellModeRow              = PcdGet32 (PcdSetupConOutRow);
+
+  Status = gBS->HandleProtocol (
+                  gST->ConsoleOutHandle,
+                  &gEfiGraphicsOutputProtocolGuid,
+                  (VOID **)&GraphicsOutput
+                  );
+  if (EFI_ERROR (Status)) {
+    GraphicsOutput = NULL;
+  }
+
+  Status = gBS->HandleProtocol (
+                  gST->ConsoleOutHandle,
+                  &gEfiSimpleTextOutProtocolGuid,
+                  (VOID **)&SimpleTextOut
+                  );
+  if (EFI_ERROR (Status)) {
+    SimpleTextOut = NULL;
+  }
+
+  if ((GraphicsOutput == NULL) || (SimpleTextOut == NULL)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  MaxGopMode  = GraphicsOutput->Mode->MaxMode;
+  MaxTextMode = SimpleTextOut->Mode->MaxMode;
+
+  //
+  // 1. If current video resolution is same with new video resolution,
+  //    video resolution need not be changed.
+  //    1.1. If current text mode is same with new text mode, text mode need not be change.
+  //    1.2. If current text mode is different with new text mode, text mode need be change to new text mode.
+  // 2. If current video resolution is different with new video resolution, we need restart whole console drivers.
+  //
+  for (ModeNumber = 0; ModeNumber < MaxGopMode; ModeNumber++) {
+    Status = GraphicsOutput->QueryMode (
+                               GraphicsOutput,
+                               ModeNumber,
+                               &SizeOfInfo,
+                               &Info
+                               );
+    if (!EFI_ERROR (Status)) {
+      if ((Info->HorizontalResolution == mShellHorizontalResolution) &&
+          (Info->VerticalResolution == mShellVerticalResolution))
+      {
+        if ((GraphicsOutput->Mode->Info->HorizontalResolution == mShellHorizontalResolution) &&
+            (GraphicsOutput->Mode->Info->VerticalResolution == mShellVerticalResolution))
+        {
+          //
+          // If current video resolution is same with new resolution,
+          // then check if current text mode is same with new text mode.
+          //
+          Status = SimpleTextOut->QueryMode (SimpleTextOut, SimpleTextOut->Mode->Mode, &CurrentColumn, &CurrentRow);
+          ASSERT_EFI_ERROR (Status);
+          if ((CurrentColumn == mShellModeColumn) && (CurrentRow == mShellModeRow)) {
+            //
+            // Current text mode is same with new text mode, text mode need not be change.
+            //
+            FreePool (Info);
+            return EFI_SUCCESS;
+          } else {
+            //
+            // Current text mode is different with new text mode, text mode need be change to new text mode.
+            //
+            for (Index = 0; Index < MaxTextMode; Index++) {
+              Status = SimpleTextOut->QueryMode (SimpleTextOut, Index, &CurrentColumn, &CurrentRow);
+              if (!EFI_ERROR (Status)) {
+                if ((CurrentColumn == mShellModeColumn) && (CurrentRow == mShellModeRow)) {
+                  //
+                  // New text mode is supported, set it.
+                  //
+                  Status = SimpleTextOut->SetMode (SimpleTextOut, Index);
+                  ASSERT_EFI_ERROR (Status);
+                  //
+                  // Update text mode PCD.
+                  //
+                  Status = PcdSet32S (PcdConOutColumn, mShellModeColumn);
+                  ASSERT_EFI_ERROR (Status);
+
+                  Status = PcdSet32S (PcdConOutRow, mShellModeRow);
+                  ASSERT_EFI_ERROR (Status);
+
+                  FreePool (Info);
+                  return EFI_SUCCESS;
+                }
+              }
+            }
+
+            if (Index == MaxTextMode) {
+              //
+              // If new text mode is not supported, return error.
+              //
+              FreePool (Info);
+              return EFI_UNSUPPORTED;
+            }
+          }
+        } else {
+          FreePool (Info);
+          //
+          // If current video resolution is not same with the new one, set new video resolution.
+          // In this case, the driver which produces simple text out need be restarted.
+          //
+          Status = GraphicsOutput->SetMode (GraphicsOutput, ModeNumber);
+          if (!EFI_ERROR (Status)) {
+            //
+            // Set PCD to restart GraphicsConsole and Consplitter to change video resolution
+            // and produce new text mode based on new resolution.
+            //
+            Status = PcdSet32S (PcdVideoHorizontalResolution, mShellHorizontalResolution);
+            ASSERT_EFI_ERROR (Status);
+
+            Status = PcdSet32S (PcdVideoVerticalResolution, mShellVerticalResolution);
+            ASSERT_EFI_ERROR (Status);
+
+            Status = PcdSet32S (PcdConOutColumn, mShellModeColumn);
+            ASSERT_EFI_ERROR (Status);
+
+            Status = PcdSet32S (PcdConOutRow, mShellModeRow);
+            ASSERT_EFI_ERROR (Status);
+
+            Status = gBS->LocateHandleBuffer (
+                            ByProtocol,
+                            &gEfiSimpleTextOutProtocolGuid,
+                            NULL,
+                            &HandleCount,
+                            &HandleBuffer
+                            );
+            if (!EFI_ERROR (Status)) {
+              for (Index = 0; Index < HandleCount; Index++) {
+                gBS->DisconnectController (HandleBuffer[Index], NULL, NULL);
+              }
+
+              for (Index = 0; Index < HandleCount; Index++) {
+                gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE);
+              }
+
+              if (HandleBuffer != NULL) {
+                FreePool (HandleBuffer);
+              }
+
+              break;
+            }
+          }
+        }
+      }
+
+      FreePool (Info);
+    }
+  }
+
+  if (ModeNumber == MaxGopMode) {
+    //
+    // If the new resolution is not supported, return error.
+    //
+    return EFI_UNSUPPORTED;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  The function connects the trusted consoles and then call the PP processing library interface.
+**/
+VOID
+ProcessTcgPp (
+  VOID
+  )
+{
+  gPPRequireUIConfirm |= Tcg2PhysicalPresenceLibNeedUserConfirm ();
+
+  if (gPPRequireUIConfirm) {
+    ConnectTrustedConsole ();
+  }
+
+  Tcg2PhysicalPresenceLibProcessRequest (NULL);
+}
+
+/**
+  The function connects the trusted storage to perform TPerReset.
+**/
+VOID
+ProcessTcgMor (
+  VOID
+  )
+{
+  if (IsMorBitSet ()) {
+    ConnectTrustedConsole ();
+    ConnectTrustedStorage ();
+  }
+}
+
+/**
+  Update the ConIn variable with USB Keyboard device path,if its not already exists in ConIn.
+**/
+VOID
+EnumUsbKeyboard (
+  VOID
+  )
+{
+  DEBUG ((DEBUG_INFO, "[EnumUsbKeyboard]\n"));
+  EfiBootManagerUpdateConsoleVariable (ConIn, (EFI_DEVICE_PATH_PROTOCOL *)&gUsbClassKeyboardDevicePath, NULL);
+  //
+  // Append Usb Keyboard short form DevicePath into "ConInDev"
+  //
+  EfiBootManagerUpdateConsoleVariable (ConInDev, (EFI_DEVICE_PATH_PROTOCOL *)&gUsbClassKeyboardDevicePath, NULL);
+}
+
+/**
+  Connect with predeined platform connect sequence,
+  the OEM/IBV can customize with their own connect sequence.
+
+  @param[in] BootMode          Boot mode of this boot.
+**/
+VOID
+ConnectSequence (
+  IN EFI_BOOT_MODE  BootMode
+  )
+{
+  EfiBootManagerConnectAll ();
+}
+
+/**
+  Connects Root Bridge.
+
+  @param[in] Recursive  Recursively connect controllers if TRUE
+ **/
+VOID
+ConnectRootBridge (
+  IN BOOLEAN  Recursive
+  )
+{
+  UINTN       RootBridgeHandleCount;
+  EFI_HANDLE  *RootBridgeHandleBuffer;
+  UINTN       RootBridgeIndex;
+
+  RootBridgeHandleCount = 0;
+  gBS->LocateHandleBuffer (
+         ByProtocol,
+         &gEfiPciRootBridgeIoProtocolGuid,
+         NULL,
+         &RootBridgeHandleCount,
+         &RootBridgeHandleBuffer
+         );
+  for (RootBridgeIndex = 0; RootBridgeIndex < RootBridgeHandleCount; RootBridgeIndex++) {
+    gBS->ConnectController (RootBridgeHandleBuffer[RootBridgeIndex], NULL, NULL, Recursive);
+  }
+}
+
+/**
+  Add console variable device paths.
+
+  @param[in] ConsoleType         ConIn or ConOut
+  @param[in] ConsoleDevicePath   Device path to be added
+**/
+VOID
+AddConsoleVariable (
+  IN CONSOLE_TYPE     ConsoleType,
+  IN EFI_DEVICE_PATH  *ConsoleDevicePath
+  )
+{
+  EFI_DEVICE_PATH  *TempDevicePath;
+  EFI_DEVICE_PATH  *Instance;
+  UINTN            Size;
+  EFI_HANDLE       GraphicsControllerHandle;
+  EFI_DEVICE_PATH  *GopDevicePath;
+
+  TempDevicePath = DuplicateDevicePath (ConsoleDevicePath);
+  do {
+    Instance = GetNextDevicePathInstance (&TempDevicePath, &Size);
+    if (Instance == NULL) {
+      break;
+    }
+
+    switch (ConsoleType) {
+      case ConIn:
+        if (IsUsbShortForm (Instance)) {
+          //
+          // Append Usb Keyboard short form DevicePath into "ConInDev"
+          //
+          EfiBootManagerUpdateConsoleVariable (ConInDev, Instance, NULL);
+        }
+
+        EfiBootManagerUpdateConsoleVariable (ConsoleType, Instance, NULL);
+        break;
+      case ConOut:
+        GraphicsControllerHandle = IsVideoController (Instance);
+        if (GraphicsControllerHandle == NULL) {
+          EfiBootManagerUpdateConsoleVariable (ConsoleType, Instance, NULL);
+        } else {
+          //
+          // Connect the GOP driver
+          //
+          gBS->ConnectController (GraphicsControllerHandle, NULL, NULL, TRUE);
+          //
+          // Get the GOP device path
+          // NOTE: We may get a device path that contains Controller node in it.
+          //
+          GopDevicePath = EfiBootManagerGetGopDevicePath (GraphicsControllerHandle);
+          if (GopDevicePath != NULL) {
+            EfiBootManagerUpdateConsoleVariable (ConsoleType, GopDevicePath, NULL);
+          }
+        }
+
+        break;
+      default:
+        ASSERT (FALSE);
+        break;
+    }
+
+    FreePool (Instance);
+  } while (TempDevicePath != NULL);
+
+  if (TempDevicePath != NULL) {
+    FreePool (TempDevicePath);
+  }
+}
+
+/**
+  This is the callback function for PCI ENUMERATION COMPLETE.
+
+  @param[in] Event      The Event this notify function registered to.
+  @param[in] Context    Pointer to the context data registered to the Event.
+**/
+VOID
+EFIAPI
+BdsPciEnumCompleteCallback (
+  IN EFI_EVENT  Event,
+  IN VOID       *Context
+  )
+{
+  EFI_STATUS                Status;
+  VOID                      *ProtocolPointer;
+  EFI_DEVICE_PATH_PROTOCOL  *VarConOut;
+  EFI_DEVICE_PATH_PROTOCOL  *VarConIn;
+
+  Status = EFI_SUCCESS;
+
+  //
+  // Check if this is first time called by EfiCreateProtocolNotifyEvent() or not,
+  // if it is, we will skip it until real event is triggered
+  //
+  Status = gBS->LocateProtocol (&gEfiPciEnumerationCompleteProtocolGuid, NULL, (VOID **)&ProtocolPointer);
+  if (EFI_SUCCESS != Status) {
+    return;
+  }
+
+  // gBS->CloseEvent (Event);
+
+  DEBUG ((DEBUG_INFO, "Event BdsPciEnumCompleteCallback callback starts\n"));
+
+  gBootMode = GetBootModeHob ();
+
+  //
+  // Fill ConIn/ConOut in Full Configuration boot mode
+  //
+  DEBUG ((DEBUG_INFO, "PlatformBootManagerInit - %x\n", gBootMode));
+
+  if ((gBootMode == BOOT_WITH_FULL_CONFIGURATION) ||
+      (gBootMode == BOOT_WITH_DEFAULT_SETTINGS) ||
+      (gBootMode == BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS) ||
+      (gBootMode == BOOT_IN_RECOVERY_MODE))
+  {
+    GetEfiGlobalVariable2 (L"ConOut", (VOID **)&VarConOut, NULL);
+    if (VarConOut != NULL) {
+      FreePool (VarConOut);
+    }
+
+    GetEfiGlobalVariable2 (L"ConIn", (VOID **)&VarConIn, NULL);
+    if (VarConIn  != NULL) {
+      FreePool (VarConIn);
+    }
+
+    //
+    // Only fill ConIn/ConOut when ConIn/ConOut is empty because we may drop to Full Configuration boot mode in non-first boot
+    //
+    if ((VarConOut == NULL) || (VarConIn == NULL)) {
+      if (PcdGetSize (PcdTrustedConsoleOutputDevicePath) >= sizeof (EFI_DEVICE_PATH_PROTOCOL)) {
+        AddConsoleVariable (ConOut, PcdGetPtr (PcdTrustedConsoleOutputDevicePath));
+      }
+
+      if (PcdGetSize (PcdTrustedConsoleInputDevicePath) >= sizeof (EFI_DEVICE_PATH_PROTOCOL)) {
+        AddConsoleVariable (ConIn, PcdGetPtr (PcdTrustedConsoleInputDevicePath));
+      }
+    }
+  }
+
+  //
+  // Enumerate USB keyboard
+  //
+  EnumUsbKeyboard ();
+
+  //
+  // For trusted console it must be handled here.
+  //
+  UpdateGraphicConOut (TRUE);
+
+  //
+  // Register Boot Options
+  //
+  RegisterDefaultBootOption ();
+
+  //
+  // Register Static Hot keys
+  //
+  RegisterStaticHotkey ();
+
+  //
+  // Process Physical Preo
+  //
+  PERF_START_EX (NULL, "EventRec", NULL, AsmReadTsc (), 0x7010);
+  if (PcdGetBool (PcdTpm2Enable)) {
+    ProcessTcgPp ();
+    ProcessTcgMor ();
+  }
+
+  PERF_END_EX (NULL, "EventRec", NULL, AsmReadTsc (), 0x7011);
+
+  //
+  // Perform memory test
+  // We should make all UEFI memory and GCD information populated before ExitPmAuth.
+  // SMM may consume these information.
+  //
+  MemoryTest ((EXTENDMEM_COVERAGE_LEVEL)PcdGet32 (PcdPlatformMemoryCheckLevel));
+}
+
+/**
+  This is the callback function for Smm Ready To Lock.
+
+  @param[in] Event      The Event this notify function registered to.
+  @param[in] Context    Pointer to the context data registered to the Event.
+**/
+VOID
+EFIAPI
+BdsSmmReadyToLockCallback (
+  IN EFI_EVENT  Event,
+  IN VOID       *Context
+  )
+{
+  VOID        *ProtocolPointer;
+  EFI_STATUS  Status;
+
+  //
+  // Check if this is first time called by EfiCreateProtocolNotifyEvent() or not,
+  // if it is, we will skip it until real event is triggered
+  //
+  Status = gBS->LocateProtocol (&gEfiDxeSmmReadyToLockProtocolGuid, NULL, (VOID **)&ProtocolPointer);
+  if (EFI_SUCCESS != Status) {
+    return;
+  }
+
+  DEBUG ((DEBUG_INFO, "Event gEfiDxeSmmReadyToLockProtocolGuid callback starts\n"));
+
+  //
+  // Dispatch the deferred 3rd party images.
+  //
+  EfiBootManagerDispatchDeferredImages ();
+
+  //
+  // For non-trusted console it must be handled here.
+  //
+  UpdateGraphicConOut (FALSE);
+}
+
+/**
+  ReadyToBoot callback to set video and text mode for internal shell boot.
+  That will not connect USB controller while CSM and FastBoot are disabled, we need to connect them
+  before booting to Shell for showing USB devices in Shell.
+
+  When FastBoot is enabled and Windows Console is the chosen Console behavior, input devices will not be connected
+  by default. Hence, when booting to EFI shell, connecting input consoles are required.
+
+  @param[in]  Event   Pointer to this event
+  @param[in]  Context Event handler private data
+**/
+VOID
+EFIAPI
+BdsReadyToBootCallback (
+  IN  EFI_EVENT  Event,
+  IN  VOID       *Context
+  )
+{
+  DEBUG ((DEBUG_INFO, "BdsReadyToBootCallback\n"));
+
+  if (BootCurrentIsInternalShell ()) {
+    ChangeModeForInternalShell ();
+    EfiBootManagerConnectAllDefaultConsoles ();
+    gDS->Dispatch ();
+  }
+}
+
+/**
+  Before console after trusted console event callback
+
+  @param[in] Event      The Event this notify function registered to.
+  @param[in] Context    Pointer to the context data registered to the Event.
+**/
+VOID
+EFIAPI
+BdsBeforeConsoleAfterTrustedConsoleCallback (
+  IN EFI_EVENT  Event,
+  IN VOID       *Context
+  )
+{
+  DEBUG ((DEBUG_INFO, "Event gBdsEventBeforeConsoleBeforeEndOfDxeGuid callback starts\n"));
+
+  //
+  // Connect Root Bridge to make PCI BAR resource allocated and all PciIo created
+  //
+  ConnectRootBridge (FALSE);
+}
+
+/**
+  Before console before end of DXE event callback
+
+  @param[in] Event      The Event this notify function registered to.
+  @param[in] Context    Pointer to the context data registered to the Event.
+**/
+VOID
+EFIAPI
+BdsBeforeConsoleBeforeEndOfDxeGuidCallback (
+  IN EFI_EVENT  Event,
+  IN VOID       *Context
+  )
+{
+  DEBUG ((DEBUG_INFO, "Event gBdsBeforeConsoleBeforeEndOfDxeGuid callback starts\n"));
+}
+
+/**
+  Handles possible IPMI boot overrides by modifying the LoadOptions variable.
+  Uses sorting function installed in BootOptionPriorityProtocol if the protocol
+  is installed and a valid IPMI override is detected.
+
+  @retval  EFI_SUCCESS    Boot override successful, or not necessary.
+  @retval  EFI_NOT_FOUND  Attempted to override boot to an unsupported boot option.
+**/
+EFI_STATUS
+HandleIpmiBootOverride (
+  VOID
+  )
+{
+  UINT8                                        NvIpmiBootOverride;
+  UINT8                                        Index;
+  UINT8                                        CurrentIpmiBootOverride;
+  UINT8                                        *GetBootOptionsBuffer;
+  UINT8                                        *SetBootOptionsBuffer;
+  UINTN                                        BootOptionCount;
+  UINTN                                        DataSize;
+  IPMI_GET_BOOT_OPTIONS_REQUEST                BootOptionsRequest;
+  IPMI_GET_BOOT_OPTIONS_RESPONSE               *BootOptionsResponse;
+  IPMI_BOOT_OPTIONS_RESPONSE_PARAMETER_5       *BootOptionsParameterData;
+  IPMI_SET_BOOT_OPTIONS_REQUEST                *SetBootOptionsRequest;
+  IPMI_SET_BOOT_OPTIONS_RESPONSE               SetBootOptionsResponse;
+  IPMI_BOOT_OPTIONS_RESPONSE_PARAMETER_5       *SetBootOptionsParameterData;
+  EFI_BOOT_MANAGER_LOAD_OPTION                 *LoadOptionToManipulate;
+  EFI_BOOT_MANAGER_LOAD_OPTION                 *BootOptions;
+  EFI_STATUS                                   Status;
+  AMD_BOARD_BDS_BOOT_OPTION_PRIORITY_PROTOCOL  *BootOptionPriorityProtocol;
+  EFI_HANDLE                                   *BootPriorityHandles;
+  UINTN                                        BootPriorityCount;
+  UINTN                                        BootPriorityIndex;
+  BOOLEAN                                      ValidBootPriorityOverride;
+
+  ZeroMem (&BootOptionsRequest, sizeof (IPMI_GET_BOOT_OPTIONS_REQUEST));
+  ZeroMem (&SetBootOptionsResponse, sizeof (IPMI_SET_BOOT_OPTIONS_RESPONSE));
+
+  LoadOptionToManipulate    = NULL;
+  Status                    = EFI_SUCCESS;
+  ValidBootPriorityOverride = FALSE;
+  // setup buffers
+  GetBootOptionsBuffer = (UINT8 *)AllocateZeroPool (sizeof (BootOptionsResponse) + sizeof (IPMI_BOOT_OPTIONS_RESPONSE_PARAMETER_5));
+  SetBootOptionsBuffer = (UINT8 *)AllocateZeroPool (sizeof (SetBootOptionsRequest) + sizeof (IPMI_BOOT_OPTIONS_RESPONSE_PARAMETER_5));
+
+  // setup parameter data
+  BootOptionsRequest.ParameterSelector.Bits.ParameterSelector = IPMI_BOOT_OPTIONS_PARAMETER_BOOT_FLAGS;
+  BootOptionsResponse                                         = (IPMI_GET_BOOT_OPTIONS_RESPONSE *)&GetBootOptionsBuffer[0];
+  Status                                                      = IpmiGetSystemBootOptions (&BootOptionsRequest, BootOptionsResponse);
+  BootOptionsParameterData                                    = (IPMI_BOOT_OPTIONS_RESPONSE_PARAMETER_5 *)BootOptionsResponse->ParameterData;
+
+  if (EFI_ERROR (Status)) {
+    Status = EFI_UNSUPPORTED;
+    goto end;
+  }
+
+  // setup SetBootOptions parameter data
+  SetBootOptionsRequest       = (IPMI_SET_BOOT_OPTIONS_REQUEST *)&SetBootOptionsBuffer[0];
+  SetBootOptionsParameterData = (IPMI_BOOT_OPTIONS_RESPONSE_PARAMETER_5 *)SetBootOptionsRequest->ParameterData;
+
+  BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot);
+
+  // if received valid IPMI data, then override boot option
+  if (!BootOptionsResponse->ParameterValid.Bits.ParameterValid && BootOptionsParameterData->Data1.Bits.BootFlagValid) {
+    // get non volatile IpmiBootOverride variable
+    DataSize = sizeof (UINT8);
+    Status   = gRT->GetVariable (
+                      IPMI_BOOT_OVERRIDE_VAR_NAME,
+                      &gEfiCallerIdGuid,
+                      NULL,
+                      &DataSize,
+                      &NvIpmiBootOverride
+                      );
+    if (EFI_ERROR (Status)) {
+      NvIpmiBootOverride = IPMI_BOOT_DEVICE_SELECTOR_NO_OVERRIDE;
+    }
+
+    CurrentIpmiBootOverride = BootOptionsParameterData->Data2.Bits.BootDeviceSelector;
+
+    // Handle platform specific boot priority override
+    Status = gBS->LocateHandleBuffer (
+                    ByProtocol,
+                    &gAmdBoardBdsBootOptionPriorityProtocolGuid,
+                    NULL,
+                    &BootPriorityCount,
+                    &BootPriorityHandles
+                    );
+
+    if (!EFI_ERROR (Status)) {
+      for (BootPriorityIndex = 0; BootPriorityIndex < BootPriorityCount; BootPriorityIndex++) {
+        Status = gBS->HandleProtocol (
+                        BootPriorityHandles[BootPriorityIndex],
+                        &gAmdBoardBdsBootOptionPriorityProtocolGuid,
+                        (VOID **)&BootOptionPriorityProtocol
+                        );
+        if (!EFI_ERROR (Status) &&
+            (BootOptionPriorityProtocol->IpmiBootDeviceSelectorType == CurrentIpmiBootOverride))
+        {
+          DEBUG ((DEBUG_INFO, "Valid BootOptionPriority Override detected\n"));
+          ValidBootPriorityOverride = TRUE;
+          break;
+        }
+      }
+    }
+
+    if (CurrentIpmiBootOverride == IPMI_BOOT_DEVICE_SELECTOR_BIOS_SETUP) {
+      DEBUG ((DEBUG_INFO, "[Bds]BiosSetup option override detected via IPMI\n"));
+      // need to find boot option corresponding to BiosSetup
+      for (Index = 0; Index < BootOptionCount; Index++) {
+        if ((StrCmp (BootOptions[Index].Description, L"Enter Setup") == 0) && (BootOptions[Index].Attributes == (LOAD_OPTION_CATEGORY_APP | LOAD_OPTION_ACTIVE | LOAD_OPTION_HIDDEN))) {
+          LoadOptionToManipulate = &BootOptions[Index];
+        } else if (StrCmp (BootOptions[Index].Description, L"Enter Setup") == 0) {
+          // delete duplicate BiosSetup Menu option
+          EfiBootManagerDeleteLoadOptionVariable (BootOptions[Index].OptionNumber, LoadOptionTypeBoot);
+        }
+      }
+
+      if (LoadOptionToManipulate == NULL) {
+        Status = EFI_UNSUPPORTED;
+        goto end;
+      }
+
+      // have Load option for bios setup, now update loadoptions
+      Status                              = EfiBootManagerDeleteLoadOptionVariable (LoadOptionToManipulate->OptionNumber, LoadOptionTypeBoot);
+      LoadOptionToManipulate->Attributes &= LOAD_OPTION_CATEGORY_BOOT;
+      LoadOptionToManipulate->Attributes |= (LOAD_OPTION_ACTIVE | LOAD_OPTION_HIDDEN);
+      Status                              = EfiBootManagerAddLoadOptionVariable (LoadOptionToManipulate, 0); // add back in loadoptions in 0th index (first option)
+    } else if (CurrentIpmiBootOverride == IPMI_BOOT_DEVICE_SELECTOR_PXE) {
+      DEBUG ((DEBUG_INFO, "[Bds]PXE option override detected via IPMI\n"));
+
+      if (ValidBootPriorityOverride) {
+        EfiBootManagerSortLoadOptionVariable (LoadOptionTypeBoot, BootOptionPriorityProtocol->Compare);
+      } else {
+        EfiBootManagerSortLoadOptionVariable (LoadOptionTypeBoot, CompareBootOptionPxePriority);
+      }
+    } else if (CurrentIpmiBootOverride == IPMI_BOOT_DEVICE_SELECTOR_HARDDRIVE) {
+      DEBUG ((DEBUG_INFO, "[Bds]HDD option override detected via IPMI\n"));
+      if (ValidBootPriorityOverride) {
+        EfiBootManagerSortLoadOptionVariable (LoadOptionTypeBoot, BootOptionPriorityProtocol->Compare);
+      } else {
+        EfiBootManagerSortLoadOptionVariable (LoadOptionTypeBoot, CompareBootOptionHddPriority);
+      }
+    } else if ((CurrentIpmiBootOverride == IPMI_BOOT_DEVICE_SELECTOR_NO_OVERRIDE) && (CurrentIpmiBootOverride != NvIpmiBootOverride)) {
+      // delete BiosSetup option corresponding to the override
+      Status = EfiBootManagerDeleteLoadOptionVariable (BootOptions[0].OptionNumber, LoadOptionTypeBoot);
+      // re sort boot options
+      EfiBootManagerSortLoadOptionVariable (LoadOptionTypeBoot, CompareBootOption);
+    }
+
+    // if Ipmi override not persistent, reset boot option to None and persistent to true
+    if (!BootOptionsParameterData->Data1.Bits.PersistentOptions) {
+      SetBootOptionsRequest->ParameterValid.Bits.ParameterSelector = IPMI_BOOT_OPTIONS_PARAMETER_BOOT_FLAGS;
+      CopyMem (SetBootOptionsParameterData, BootOptionsParameterData, sizeof (IPMI_BOOT_OPTIONS_RESPONSE_PARAMETER_5));
+      SetBootOptionsParameterData->Data1.Bits.PersistentOptions  = 1;                                     // persistent
+      SetBootOptionsParameterData->Data2.Bits.BootDeviceSelector = IPMI_BOOT_DEVICE_SELECTOR_NO_OVERRIDE; // revert to no override
+      Status                                                     = IpmiSetSystemBootOptions (SetBootOptionsRequest, &SetBootOptionsResponse);
+    }
+
+    Status = gRT->SetVariable (
+                    IPMI_BOOT_OVERRIDE_VAR_NAME,
+                    &gEfiCallerIdGuid,
+                    EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+                    sizeof (UINT8),
+                    &CurrentIpmiBootOverride
+                    );
+  }
+
+end:
+  // Free buffers
+  FreePool (GetBootOptionsBuffer);
+  FreePool (SetBootOptionsBuffer);
+  return Status;
+}
+
+/**
+  After console ready before boot option event callback.
+
+  @param[in] Event      The Event this notify function registered to.
+  @param[in] Context    Pointer to the context data registered to the Event.
+**/
+VOID
+EFIAPI
+BdsAfterConsoleReadyBeforeBootOptionCallback (
+  IN EFI_EVENT  Event,
+  IN VOID       *Context
+  )
+{
+  EFI_BOOT_MODE  LocalBootMode;
+  EFI_STATUS     Status;
+  BOOLEAN        IsFirstBoot;
+  UINTN          DataSize;
+
+  DEBUG ((DEBUG_INFO, "Event gBdsAfterConsoleReadyBeforeBootOptionEvent callback starts\n"));
+  //
+  // Get current Boot Mode
+  //
+  LocalBootMode = gBootMode;
+  DEBUG ((DEBUG_INFO, "Current local bootmode - %x\n", LocalBootMode));
+
+  //
+  // Go the different platform policy with different boot mode
+  // Notes: this part code can be change with the table policy
+  //
+  switch (LocalBootMode) {
+    case BOOT_ASSUMING_NO_CONFIGURATION_CHANGES:
+    case BOOT_WITH_MINIMAL_CONFIGURATION:
+    case BOOT_ON_S4_RESUME:
+      //
+      // Perform some platform specific connect sequence
+      //
+      PERF_START_EX (NULL, "EventRec", NULL, AsmReadTsc (), 0x7050);
+      ConnectSequence (LocalBootMode);
+      PERF_END_EX (NULL, "EventRec", NULL, AsmReadTsc (), 0x7051);
+
+      break;
+
+    case BOOT_WITH_FULL_CONFIGURATION:
+    case BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS:
+    case BOOT_WITH_DEFAULT_SETTINGS:
+    default:
+      //
+      // Perform some platform specific connect sequence
+      //
+      ConnectSequence (LocalBootMode);
+
+      //
+      // Only in Full Configuration boot mode we do the enumeration of boot device
+      //
+      //
+      // Dispatch all but Storage Oprom explicitly, because we assume Int13Thunk driver is there.
+      //
+
+      //
+      // PXE boot option may appear after boot option enumeration
+      //
+
+      EfiBootManagerRefreshAllBootOption ();
+      DataSize = sizeof (BOOLEAN);
+      Status   = gRT->GetVariable (
+                        IS_FIRST_BOOT_VAR_NAME,
+                        &gEfiCallerIdGuid,
+                        NULL,
+                        &DataSize,
+                        &IsFirstBoot
+                        );
+      if (EFI_ERROR (Status)) {
+        //
+        // If can't find the variable, see it as the first boot
+        //
+        IsFirstBoot = TRUE;
+      }
+
+      if (IsFirstBoot) {
+        //
+        // In the first boot, sort the boot option
+        //
+        EfiBootManagerSortLoadOptionVariable (LoadOptionTypeBoot, CompareBootOption);
+        IsFirstBoot = FALSE;
+        Status      = gRT->SetVariable (
+                             IS_FIRST_BOOT_VAR_NAME,
+                             &gEfiCallerIdGuid,
+                             EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+                             sizeof (BOOLEAN),
+                             &IsFirstBoot
+                             );
+      }
+
+      break;
+  }
+
+  HandleIpmiBootOverride ();
+
+  Print (L"Press F2 for Setup, or F7 for BootMenu!\n");
+
+ #ifdef INTERNAL_IDS
+  PrintSocOpnInfo ();
+ #endif
+}
+
+#ifdef INTERNAL_IDS
+
+/**
+  Display CPU OPN on Splash screen After console ready.
+  @retval EFI_SUCCESS
+**/
+EFI_STATUS
+PrintSocOpnInfo (
+  IN  VOID
+  )
+{
+  CHAR16  OpnChar[(sizeof (UINT64) / sizeof (UINT8)) * (MSR_CPUID_NAME_STRING5 - MSR_CPUID_NAME_STRING0 + 1) + 1];
+  UINT32  Msr;
+  UINT64  Value;
+  UINTN   CharIndex;
+  UINTN   ByteIndex;
+
+  CharIndex = 0;
+  for (Msr = MSR_CPUID_NAME_STRING0; Msr <= MSR_CPUID_NAME_STRING5; Msr++) {
+    Value = AsmReadMsr64 (Msr);
+    for (ByteIndex = 0; ByteIndex < (sizeof (UINT64) / sizeof (UINT8)); ByteIndex++) {
+      OpnChar[CharIndex] = (Value & 0xFF);
+      CharIndex++;
+      Value = RShiftU64 (Value, 8);
+    }
+  }
+
+  OpnChar[CharIndex] = L'\0';
+
+  DEBUG ((DEBUG_INFO, "\nProcessor OPN: "));
+  DEBUG ((DEBUG_INFO, "%s\n", OpnChar));
+
+  Print (L"Processor OPN: ");
+  Print (OpnChar);
+  Print (L"\n\r");
+
+  return EFI_SUCCESS;
+}
+
+#endif
diff --git a/Platform/AMD/AmdMinBoardPkg/Library/BoardBdsHookLib/BoardBdsHookLib.inf b/Platform/AMD/AmdMinBoardPkg/Library/BoardBdsHookLib/BoardBdsHookLib.inf
new file mode 100644
index 0000000000..23e834e332
--- /dev/null
+++ b/Platform/AMD/AmdMinBoardPkg/Library/BoardBdsHookLib/BoardBdsHookLib.inf
@@ -0,0 +1,105 @@
+### @file
+# Module Information file for the Bds Hook Library.
+#
+# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+# Copyright (C) 2023- 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+###
+
+[Defines]
+  INF_VERSION                    = 0x00010017
+  BASE_NAME                      = BoardBdsHookLib
+  FILE_GUID                      = A500CFFB-26DA-4CB1-B214-EC16524C9733
+  VERSION_STRING                 = 1.0
+  MODULE_TYPE                    = DXE_DRIVER
+  LIBRARY_CLASS                  = BoardBdsHookLib|DXE_DRIVER
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+  DevicePathLib
+  DxeServicesLib
+  DxeServicesTableLib
+  HiiLib
+  HobLib
+  IpmiCommandLib
+  IpmiLib
+  MemoryAllocationLib
+  PcdLib
+  PerformanceLib
+  PrintLib
+  SortLib
+  Tcg2PhysicalPresenceLib
+  TimerLib
+  UefiBootManagerLib
+  UefiBootServicesTableLib
+  UefiLib
+  UefiRuntimeServicesTableLib
+
+[Packages]
+  AmdMinBoardPkg/AmdMinBoardPkg.dec
+  BoardModulePkg/BoardModulePkg.dec
+  IpmiFeaturePkg/IpmiFeaturePkg.dec
+  ManageabilityPkg/ManageabilityPkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  MinPlatformPkg/MinPlatformPkg.dec
+  SecurityPkg/SecurityPkg.dec
+
+[Pcd]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConInConnectOnDemand            ## PRODUCES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutColumn                    ## PRODUCES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutRow                       ## PRODUCES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupConOutColumn               ## CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupConOutRow                  ## CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoHorizontalResolution  ## CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoVerticalResolution    ## CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution       ## PRODUCES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution         ## PRODUCES
+  gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut                   ## PRODUCES
+  gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly                  ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdPlatformMemoryCheckLevel         ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdShellFile                        ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdShellFileDesc                    ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdTpm2Enable                       ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdTrustedConsoleInputDevicePath    ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdTrustedConsoleOutputDevicePath   ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdTrustedStorageDevicePath         ## CONSUMES
+
+[Sources]
+  BoardBdsHook.h
+  BoardBdsHookLib.c
+  BoardBootOption.c
+  BoardMemoryTest.c
+
+[Protocols]
+  gAmdBoardBdsBootOptionPriorityProtocolGuid    ## CONSUMES
+  gEfiCpuIo2ProtocolGuid                        ## CONSUMES
+  gEfiDevicePathToTextProtocolGuid              ## CONSUMES
+  gEfiDiskInfoProtocolGuid                      ## CONSUMES
+  gEfiDxeSmmReadyToLockProtocolGuid
+  gEfiDxeSmmReadyToLockProtocolGuid             ## PRODUCES
+  gEfiFirmwareVolume2ProtocolGuid               ## CONSUMES
+  gEfiFormBrowser2ProtocolGuid                  ## CONSUMES
+  gEfiGenericMemTestProtocolGuid                ## CONSUMES
+  gEfiGenericMemTestProtocolGuid                ## CONSUMES
+  gEfiPciIoProtocolGuid                         ## CONSUMES
+  gEfiPciRootBridgeIoProtocolGuid               ## CONSUMES
+  gEfiSimpleTextInputExProtocolGuid             ## CONSUMES
+
+[Guids]
+  gBdsEventAfterConsoleReadyBeforeBootOptionGuid
+  gBdsEventBeforeConsoleAfterTrustedConsoleGuid
+  gBdsEventBeforeConsoleBeforeEndOfDxeGuid
+  gEfiEndOfDxeEventGroupGuid                    ## CONSUMES
+  gEfiGlobalVariableGuid                        ## PRODUCES
+  gEfiMemoryOverwriteControlDataGuid            ## PRODUCES
+
+[Depex.common.DXE_DRIVER]
+  gEfiVariableArchProtocolGuid
+
+[Depex]
+  TRUE
diff --git a/Platform/AMD/AmdMinBoardPkg/Library/BoardBdsHookLib/BoardBootOption.c b/Platform/AMD/AmdMinBoardPkg/Library/BoardBdsHookLib/BoardBootOption.c
new file mode 100644
index 0000000000..16a47c2f82
--- /dev/null
+++ b/Platform/AMD/AmdMinBoardPkg/Library/BoardBdsHookLib/BoardBootOption.c
@@ -0,0 +1,754 @@
+/** @file
+  Driver for Platform Boot Options support.
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  Copyright (C) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "BoardBdsHook.h"
+
+EFI_GUID  gUefiShellFileGuid = { 0 };
+EFI_GUID  mUiFile            = {
+  0x462CAA21, 0x7614, 0x4503, { 0x83, 0x6E, 0x8A, 0xB6, 0xF4, 0x66, 0x23, 0x31 }
+};
+EFI_GUID  mBootMenuFile = {
+  0xEEC25BDC, 0x67F2, 0x4D95, { 0xB1, 0xD5, 0xF8, 0x1B, 0x20, 0x39, 0xD1, 0x1D }
+};
+
+BOOLEAN    mContinueBoot  = FALSE;
+BOOLEAN    mBootMenuBoot  = FALSE;
+BOOLEAN    mPxeBoot       = FALSE;
+BOOLEAN    mHotKeypressed = FALSE;
+EFI_EVENT  HotKeyEvent    = NULL;
+
+UINTN  mBootMenuOptionNumber;
+UINTN  mSetupOptionNumber;
+
+/**
+  This function will create a SHELL BootOption to boot.
+
+  @return Shell Device path for booting.
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+BdsCreateShellDevicePath (
+  VOID
+  )
+{
+  UINTN                          FvHandleCount;
+  EFI_HANDLE                     *FvHandleBuffer;
+  UINTN                          Index;
+  EFI_STATUS                     Status;
+  EFI_FIRMWARE_VOLUME2_PROTOCOL  *Fv;
+  UINTN                          Size;
+  UINT32                         AuthenticationStatus;
+  EFI_DEVICE_PATH_PROTOCOL       *DevicePath;
+  VOID                           *Buffer;
+
+  DevicePath = NULL;
+  Status     = EFI_SUCCESS;
+
+  DEBUG ((DEBUG_INFO, "BdsCreateShellDevicePath\n"));
+  gBS->LocateHandleBuffer (
+         ByProtocol,
+         &gEfiFirmwareVolume2ProtocolGuid,
+         NULL,
+         &FvHandleCount,
+         &FvHandleBuffer
+         );
+
+  for (Index = 0; Index < FvHandleCount; Index++) {
+    gBS->HandleProtocol (
+           FvHandleBuffer[Index],
+           &gEfiFirmwareVolume2ProtocolGuid,
+           (VOID **)&Fv
+           );
+
+    Buffer = NULL;
+    Size   = 0;
+    Status = Fv->ReadSection (
+                   Fv,
+                   &gUefiShellFileGuid,
+                   EFI_SECTION_PE32,
+                   0,
+                   &Buffer,
+                   &Size,
+                   &AuthenticationStatus
+                   );
+    if (EFI_ERROR (Status)) {
+      //
+      // Skip if no shell file in the FV
+      //
+      continue;
+    } else {
+      //
+      // Found the shell
+      //
+      break;
+    }
+  }
+
+  if (EFI_ERROR (Status)) {
+    //
+    // No shell present
+    //
+    if (FvHandleCount) {
+      FreePool (FvHandleBuffer);
+    }
+
+    return NULL;
+  }
+
+  //
+  // Build the shell boot option
+  //
+  DevicePath = DevicePathFromHandle (FvHandleBuffer[Index]);
+
+  if (FvHandleCount) {
+    FreePool (FvHandleBuffer);
+  }
+
+  return DevicePath;
+}
+
+/**
+  Create Boot option for passed Firmware Volume.
+
+  @param[in] FileGuid         FV file name to use in FvDevicePathNode
+  @param[in] Description      Description of the load option.
+  @param[in, out] BootOption  Pointer to the load option to be initialized.
+  @param[in] Attributes       Attributes of the load option.
+  @param[in] OptionalData     Optional data of the load option.
+  @param[in] OptionalDataSize Size of the optional data of the load option.
+
+  @retval EFI_SUCCESS           The load option was initialized successfully.
+  @retval EFI_INVALID_PARAMETER BootOption, Description or FileGuid is NULL.
+**/
+EFI_STATUS
+CreateFvBootOption (
+  IN EFI_GUID *FileGuid,
+  IN CHAR16 *Description,
+  IN OUT EFI_BOOT_MANAGER_LOAD_OPTION *BootOption,
+  IN UINT32 Attributes,
+  IN UINT8 *OptionalData, OPTIONAL IN UINT32 OptionalDataSize
+  )
+{
+  EFI_STATUS                         Status;
+  EFI_DEVICE_PATH_PROTOCOL           *DevicePath;
+  EFI_LOADED_IMAGE_PROTOCOL          *LoadedImage;
+  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH  FileNode;
+  EFI_FIRMWARE_VOLUME2_PROTOCOL      *Fv;
+  UINT32                             AuthenticationStatus;
+  VOID                               *Buffer;
+  UINTN                              Size;
+
+  if ((BootOption == NULL) || (FileGuid == NULL) || (Description == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid);
+
+  if (!CompareGuid (&gUefiShellFileGuid, FileGuid)) {
+    Status = gBS->HandleProtocol (
+                    gImageHandle,
+                    &gEfiLoadedImageProtocolGuid,
+                    (VOID **)&LoadedImage
+                    );
+    if (!EFI_ERROR (Status)) {
+      Status = gBS->HandleProtocol (
+                      LoadedImage->DeviceHandle,
+                      &gEfiFirmwareVolume2ProtocolGuid,
+                      (VOID **)&Fv
+                      );
+      if (!EFI_ERROR (Status)) {
+        Buffer = NULL;
+        Size   = 0;
+        Status = Fv->ReadSection (
+                       Fv,
+                       FileGuid,
+                       EFI_SECTION_PE32,
+                       0,
+                       &Buffer,
+                       &Size,
+                       &AuthenticationStatus
+                       );
+        if (Buffer != NULL) {
+          FreePool (Buffer);
+        }
+      }
+    }
+
+    if (EFI_ERROR (Status)) {
+      return EFI_NOT_FOUND;
+    }
+
+    DevicePath = AppendDevicePathNode (
+                   DevicePathFromHandle (LoadedImage->DeviceHandle),
+                   (EFI_DEVICE_PATH_PROTOCOL *)&FileNode
+                   );
+  } else {
+    DevicePath = AppendDevicePathNode (
+                   BdsCreateShellDevicePath (),
+                   (EFI_DEVICE_PATH_PROTOCOL *)&FileNode
+                   );
+  }
+
+  Status = EfiBootManagerInitializeLoadOption (
+             BootOption,
+             LoadOptionNumberUnassigned,
+             LoadOptionTypeBoot,
+             Attributes,
+             Description,
+             DevicePath,
+             OptionalData,
+             OptionalDataSize
+             );
+  FreePool (DevicePath);
+  return Status;
+}
+
+/**
+  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[in] Key    Pointer to the load option to be found.
+  @param[in] Array  Pointer to the array of load options to be found.
+  @param[in] 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;
+}
+
+/**
+  Registers a boot option.
+
+  @param[in] FileGuid               Boot file GUID
+  @param[in] Description            Boot option description
+  @param[in] Position               Position of the new load option to put in the ****Order variable.
+  @param[in] Attributes             Boot option attributes
+  @param[in] OptionalData           Optional data of the boot option.
+  @param[in] OptionalDataSize       Size of the optional data of the boot option
+
+  @return boot option number
+**/
+UINTN
+RegisterFvBootOption (
+  IN EFI_GUID *FileGuid,
+  IN CHAR16 *Description,
+  IN UINTN Position,
+  IN UINT32 Attributes,
+  IN UINT8 *OptionalData, OPTIONAL IN UINT32 OptionalDataSize
+  )
+{
+  EFI_STATUS                    Status;
+  UINTN                         OptionIndex;
+  EFI_BOOT_MANAGER_LOAD_OPTION  NewOption;
+  EFI_BOOT_MANAGER_LOAD_OPTION  *BootOptions;
+  UINTN                         BootOptionCount;
+
+  NewOption.OptionNumber = LoadOptionNumberUnassigned;
+  Status                 = CreateFvBootOption (FileGuid, Description, &NewOption, Attributes, OptionalData, OptionalDataSize);
+  if (!EFI_ERROR (Status)) {
+    BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot);
+
+    OptionIndex = PlatformFindLoadOption (&NewOption, BootOptions, BootOptionCount);
+
+    if (OptionIndex == -1) {
+      Status = EfiBootManagerAddLoadOptionVariable (&NewOption, Position);
+      ASSERT_EFI_ERROR (Status);
+    } else {
+      NewOption.OptionNumber = BootOptions[OptionIndex].OptionNumber;
+    }
+
+    EfiBootManagerFreeLoadOption (&NewOption);
+    EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);
+  }
+
+  return NewOption.OptionNumber;
+}
+
+/**
+  Boot manager wait callback.
+
+  @param[in] TimeoutRemain The remaining timeout period
+**/
+VOID
+EFIAPI
+PlatformBootManagerWaitCallback (
+  IN UINT16  TimeoutRemain
+  )
+{
+  EFI_STATUS                         Status;
+  EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL  *TxtInEx;
+  EFI_KEY_DATA                       KeyData;
+  BOOLEAN                            PausePressed;
+
+  //
+  // Pause on PAUSE key
+  //
+  Status = gBS->HandleProtocol (gST->ConsoleInHandle, &gEfiSimpleTextInputExProtocolGuid, (VOID **)&TxtInEx);
+  ASSERT_EFI_ERROR (Status);
+
+  PausePressed = FALSE;
+
+  while (TRUE) {
+    Status = TxtInEx->ReadKeyStrokeEx (TxtInEx, &KeyData);
+    if (EFI_ERROR (Status)) {
+      break;
+    }
+
+    if (KeyData.Key.ScanCode == SCAN_PAUSE) {
+      PausePressed = TRUE;
+      break;
+    }
+  }
+
+  //
+  // Loop until non-PAUSE key pressed
+  //
+  while (PausePressed) {
+    Status = TxtInEx->ReadKeyStrokeEx (TxtInEx, &KeyData);
+    if (!EFI_ERROR (Status)) {
+      DEBUG ((
+        DEBUG_INFO,
+        "[PauseCallback] %x/%x %x/%x\n",
+        KeyData.Key.ScanCode,
+        KeyData.Key.UnicodeChar,
+        KeyData.KeyState.KeyShiftState,
+        KeyData.KeyState.KeyToggleState
+        ));
+      PausePressed = (BOOLEAN)(KeyData.Key.ScanCode == SCAN_PAUSE);
+    }
+  }
+}
+
+/**
+   Registers default boot option.
+**/
+VOID
+RegisterDefaultBootOption (
+  VOID
+  )
+{
+  UINT16  *ShellData;
+  UINT32  ShellDataSize;
+
+  ShellData     = NULL;
+  ShellDataSize = 0;
+  CopyMem (&gUefiShellFileGuid, PcdGetPtr (PcdShellFile), sizeof (GUID));
+  RegisterFvBootOption (&gUefiShellFileGuid, (CHAR16 *)PcdGetPtr (PcdShellFileDesc), (UINTN)-1, LOAD_OPTION_ACTIVE, (UINT8 *)ShellData, ShellDataSize);
+
+  //
+  // Boot Menu
+  //
+  mBootMenuOptionNumber = RegisterFvBootOption (&mBootMenuFile, L"Boot Device List", (UINTN)-1, LOAD_OPTION_CATEGORY_APP | LOAD_OPTION_ACTIVE | LOAD_OPTION_HIDDEN, NULL, 0);
+
+  if (mBootMenuOptionNumber == LoadOptionNumberUnassigned) {
+    DEBUG ((DEBUG_INFO, "BootMenuOptionNumber (%d) should not be same to LoadOptionNumberUnassigned(%d).\n", mBootMenuOptionNumber, LoadOptionNumberUnassigned));
+  }
+
+  //
+  // Boot Manager Menu
+  //
+  mSetupOptionNumber = RegisterFvBootOption (&mUiFile, L"Enter Setup", (UINTN)-1, LOAD_OPTION_CATEGORY_APP | LOAD_OPTION_ACTIVE | LOAD_OPTION_HIDDEN, NULL, 0);
+}
+
+/**
+  Registers/Unregisters boot option hotkey.
+
+  @param[in] OptionNumber  The boot option number for the key option.
+  @param[in] Key           The key input
+  @param[in] Add           Flag to indicate to add or remove a key
+**/
+VOID
+RegisterBootOptionHotkey (
+  IN UINT16         OptionNumber,
+  IN EFI_INPUT_KEY  *Key,
+  IN BOOLEAN        Add
+  )
+{
+  EFI_STATUS  Status;
+
+  if (!Add) {
+    //
+    // No enter hotkey when force to setup or there is no boot option
+    //
+    Status = EfiBootManagerDeleteKeyOptionVariable (NULL, 0, Key, NULL);
+    ASSERT (Status == EFI_SUCCESS || Status == EFI_NOT_FOUND);
+  } else {
+    //
+    // Register enter hotkey for the first boot option
+    //
+    Status = EfiBootManagerAddKeyOptionVariable (NULL, OptionNumber, 0, Key, NULL);
+    ASSERT (Status == EFI_SUCCESS || Status == EFI_ALREADY_STARTED);
+  }
+}
+
+/**
+  Detect key press callback.
+
+  @param[in] KeyData  The key data
+
+  @retval   EFI_SUCCESS
+**/
+EFI_STATUS
+EFIAPI
+DetectKeypressCallback (
+  IN EFI_KEY_DATA  *KeyData
+  )
+{
+  mHotKeypressed = TRUE;
+
+  if (HotKeyEvent != NULL) {
+    gBS->SignalEvent (HotKeyEvent);
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This function is called after all the boot options are enumerated and ordered properly.
+**/
+VOID
+RegisterStaticHotkey (
+  VOID
+  )
+{
+  EFI_INPUT_KEY  Enter;
+  EFI_KEY_DATA   F2;
+  EFI_KEY_DATA   F7;
+  BOOLEAN        EnterSetup;
+
+  EnterSetup = FALSE;
+
+  //
+  // [Enter]
+  //
+  mContinueBoot = !EnterSetup;
+  if (mContinueBoot) {
+    Enter.ScanCode    = SCAN_NULL;
+    Enter.UnicodeChar = CHAR_CARRIAGE_RETURN;
+    EfiBootManagerRegisterContinueKeyOption (0, &Enter, NULL);
+  }
+
+  //
+  // [F2]
+  //
+  if (mSetupOptionNumber != LoadOptionNumberUnassigned) {
+    F2.Key.ScanCode            = SCAN_F2;
+    F2.Key.UnicodeChar         = CHAR_NULL;
+    F2.KeyState.KeyShiftState  = EFI_SHIFT_STATE_VALID;
+    F2.KeyState.KeyToggleState = 0;
+    RegisterBootOptionHotkey ((UINT16)mSetupOptionNumber, &F2.Key, TRUE);
+  }
+
+  //
+  // Register [F7] only when the mBootMenuOptionNumber is valid
+  //
+  if (mBootMenuOptionNumber != LoadOptionNumberUnassigned) {
+    F7.Key.ScanCode            = SCAN_F7;
+    F7.Key.UnicodeChar         = CHAR_NULL;
+    F7.KeyState.KeyShiftState  = EFI_SHIFT_STATE_VALID;
+    F7.KeyState.KeyToggleState = 0;
+    mBootMenuBoot              = !EnterSetup;
+    RegisterBootOptionHotkey ((UINT16)mBootMenuOptionNumber, &F7.Key, mBootMenuBoot);
+  }
+}
+
+/**
+  Returns the boot option type of a device.
+
+  @param[in] DevicePath         The DevicePath whose boot option type is
+                                to be returned
+  @retval -1                    Device type not found
+  @retval > -1                  Device type found
+**/
+UINT8
+BootOptionType (
+  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath
+  )
+{
+  EFI_DEVICE_PATH_PROTOCOL  *Node;
+  EFI_DEVICE_PATH_PROTOCOL  *NextNode;
+
+  for (Node = DevicePath; !IsDevicePathEndType (Node); Node = NextDevicePathNode (Node)) {
+    if (DevicePathType (Node) == MESSAGING_DEVICE_PATH) {
+      //
+      // Make sure the device path points to the driver device.
+      //
+      NextNode = NextDevicePathNode (Node);
+      if (DevicePathSubType (NextNode) == MSG_DEVICE_LOGICAL_UNIT_DP) {
+        //
+        // if the next node type is Device Logical Unit, which specify the Logical Unit Number (LUN),
+        // skip it
+        //
+        NextNode = NextDevicePathNode (NextNode);
+      }
+
+      if (IsDevicePathEndType (NextNode)) {
+        if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH)) {
+          return DevicePathSubType (Node);
+        } else {
+          return MSG_SATA_DP;
+        }
+      }
+    }
+  }
+
+  return (UINT8)-1;
+}
+
+/**
+  Returns the priority number.
+
+  @param[in] BootOption     Load option to get the priority value for
+  @retval
+    OptionType                 EFI
+    ------------------------------------
+    PXE                         2
+    DVD                         4
+    USB                         6
+    NVME                        7
+    HDD                         8
+    EFI Shell                   9
+    Others                      100
+
+**/
+UINTN
+BootOptionPriority (
+  IN CONST EFI_BOOT_MANAGER_LOAD_OPTION  *BootOption
+  )
+{
+  //
+  // EFI boot options
+  //
+  switch (BootOptionType (BootOption->FilePath)) {
+    case MSG_MAC_ADDR_DP:
+    case MSG_VLAN_DP:
+    case MSG_IPv4_DP:
+    case MSG_IPv6_DP:
+      return 2;
+
+    case MSG_SATA_DP:
+    case MSG_ATAPI_DP:
+    case MSG_UFS_DP:
+    case MSG_NVME_NAMESPACE_DP:
+      return 4;
+
+    case MSG_USB_DP:
+      return 6;
+  }
+
+  if (StrCmp (BootOption->Description, (CHAR16 *)PcdGetPtr (PcdShellFileDesc)) == 0) {
+    if (PcdGetBool (PcdBootToShellOnly)) {
+      return 0;
+    }
+
+    return 9;
+  }
+
+  if (StrCmp (BootOption->Description, UEFI_HARD_DRIVE_NAME) == 0) {
+    return 8;
+  }
+
+  return 100;
+}
+
+/**
+  Returns the priority number while giving PXE highest
+  priority.
+
+  @param[in] BootOption   Load option to get the priority value for
+  @retval
+    OptionType                 EFI
+    ------------------------------------
+    PXE                         2
+    DVD                         4
+    USB                         6
+    NVME                        7
+    HDD                         8
+    EFI Shell                   9
+    Others                      100
+**/
+UINTN
+PxeBootOptionPriority (
+  IN CONST EFI_BOOT_MANAGER_LOAD_OPTION  *BootOption
+  )
+{
+  //
+  // EFI boot options
+  //
+  switch (BootOptionType (BootOption->FilePath)) {
+    case MSG_MAC_ADDR_DP:
+    case MSG_VLAN_DP:
+    case MSG_IPv4_DP:
+    case MSG_IPv6_DP:
+      return 2;
+
+    case MSG_SATA_DP:
+    case MSG_ATAPI_DP:
+    case MSG_UFS_DP:
+    case MSG_NVME_NAMESPACE_DP:
+      return 4;
+
+    case MSG_USB_DP:
+      return 6;
+  }
+
+  if (StrCmp (BootOption->Description, (CHAR16 *)PcdGetPtr (PcdShellFileDesc)) == 0) {
+    if (PcdGetBool (PcdBootToShellOnly)) {
+      return 0;
+    }
+
+    return 9;
+  }
+
+  if (StrCmp (BootOption->Description, UEFI_HARD_DRIVE_NAME) == 0) {
+    return 8;
+  }
+
+  return 100;
+}
+
+/**
+  Returns the priority number while giving HDD, DVD, and NVME highest priority.
+
+  @param[in] BootOption Load option to get the priority value for
+  @retval
+    OptionType                 EFI
+    ------------------------------------
+    NVME, DVD, HDD              2
+    PXE                         4
+    USB                         6
+    HDD                         8
+    EFI Shell                   9
+    Others                      100
+**/
+UINTN
+HddBootOptionPriority (
+  IN CONST EFI_BOOT_MANAGER_LOAD_OPTION  *BootOption
+  )
+{
+  //
+  // EFI boot options
+  //
+  switch (BootOptionType (BootOption->FilePath)) {
+    case MSG_SATA_DP:
+    case MSG_UFS_DP:
+    case MSG_NVME_NAMESPACE_DP:
+      return 2;
+
+    case MSG_ATAPI_DP:
+      return 3;
+
+    case MSG_MAC_ADDR_DP:
+    case MSG_VLAN_DP:
+    case MSG_IPv4_DP:
+    case MSG_IPv6_DP:
+      return 4;
+
+    case MSG_USB_DP:
+      return 6;
+  }
+
+  if (StrCmp (BootOption->Description, (CHAR16 *)PcdGetPtr (PcdShellFileDesc)) == 0) {
+    if (PcdGetBool (PcdBootToShellOnly)) {
+      return 0;
+    }
+
+    return 9;
+  }
+
+  if (StrCmp (BootOption->Description, UEFI_HARD_DRIVE_NAME) == 0) {
+    return 2;
+  }
+
+  return 100;
+}
+
+/**
+  Compares boot priorities of two boot options.
+
+  @param[in] Left       The left boot option
+  @param[in] Right      The right boot option
+
+  @retval           The difference between the Left and Right
+                    boot options
+ **/
+INTN
+EFIAPI
+CompareBootOption (
+  IN CONST VOID  *Left,
+  IN CONST VOID  *Right
+  )
+{
+  return BootOptionPriority ((EFI_BOOT_MANAGER_LOAD_OPTION *)Left) -
+         BootOptionPriority ((EFI_BOOT_MANAGER_LOAD_OPTION *)Right);
+}
+
+/**
+   Compares boot priorities of two boot options, while giving PXE the highest priority.
+
+  @param[in] Left       The left boot option
+  @param[in] Right      The right boot option
+
+  @retval           The difference between the Left and Right
+                    boot options
+ **/
+INTN
+EFIAPI
+CompareBootOptionPxePriority (
+  IN CONST VOID  *Left,
+  IN CONST VOID  *Right
+  )
+{
+  return PxeBootOptionPriority ((EFI_BOOT_MANAGER_LOAD_OPTION *)Left) -
+         PxeBootOptionPriority ((EFI_BOOT_MANAGER_LOAD_OPTION *)Right);
+}
+
+/**
+   Compares boot priorities of two boot options, while giving HDD the highest priority.
+
+  @param[in] Left       The left boot option
+  @param[in] Right      The right boot option
+
+  @retval           The difference between the Left and Right
+                    boot options
+ **/
+INTN
+EFIAPI
+CompareBootOptionHddPriority (
+  IN CONST VOID  *Left,
+  IN CONST VOID  *Right
+  )
+{
+  return HddBootOptionPriority ((EFI_BOOT_MANAGER_LOAD_OPTION *)Left) -
+         HddBootOptionPriority ((EFI_BOOT_MANAGER_LOAD_OPTION *)Right);
+}
diff --git a/Platform/AMD/AmdMinBoardPkg/Library/BoardBdsHookLib/BoardMemoryTest.c b/Platform/AMD/AmdMinBoardPkg/Library/BoardBdsHookLib/BoardMemoryTest.c
new file mode 100644
index 0000000000..fff0ef2993
--- /dev/null
+++ b/Platform/AMD/AmdMinBoardPkg/Library/BoardBdsHookLib/BoardMemoryTest.c
@@ -0,0 +1,83 @@
+/** @file
+  Perform the platform memory test
+
+  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "BoardBdsHook.h"
+#include <Protocol/GenericMemoryTest.h>
+
+/**
+  Perform the memory test base on the memory test intensive level,
+  and update the memory resource.
+
+  @param[in]  Level     The memory test intensive level.
+
+  @retval EFI_STATUS    Success test all the system memory and update
+                        the memory resource
+
+**/
+EFI_STATUS
+MemoryTest (
+  IN EXTENDMEM_COVERAGE_LEVEL  Level
+  )
+{
+  EFI_STATUS                        Status;
+  BOOLEAN                           RequireSoftECCInit;
+  EFI_GENERIC_MEMORY_TEST_PROTOCOL  *GenMemoryTest;
+  UINT64                            TestedMemorySize;
+  UINT64                            TotalMemorySize;
+  BOOLEAN                           ErrorOut;
+  BOOLEAN                           TestAbort;
+
+  TestedMemorySize = 0;
+  TotalMemorySize  = 0;
+  ErrorOut         = FALSE;
+  TestAbort        = FALSE;
+
+  RequireSoftECCInit = FALSE;
+
+  Status = gBS->LocateProtocol (
+                  &gEfiGenericMemTestProtocolGuid,
+                  NULL,
+                  (VOID **)&GenMemoryTest
+                  );
+  if (EFI_ERROR (Status)) {
+    return EFI_SUCCESS;
+  }
+
+  Status = GenMemoryTest->MemoryTestInit (
+                            GenMemoryTest,
+                            Level,
+                            &RequireSoftECCInit
+                            );
+  if (Status == EFI_NO_MEDIA) {
+    //
+    // The PEI codes also have the relevant memory test code to check the memory,
+    // it can select to test some range of the memory or all of them. If PEI code
+    // checks all the memory, this BDS memory test will has no not-test memory to
+    // do the test, and then the status of EFI_NO_MEDIA will be returned by
+    // "MemoryTestInit". So it does not need to test memory again, just return.
+    //
+    return EFI_SUCCESS;
+  }
+
+  do {
+    Status = GenMemoryTest->PerformMemoryTest (
+                              GenMemoryTest,
+                              &TestedMemorySize,
+                              &TotalMemorySize,
+                              &ErrorOut,
+                              TestAbort
+                              );
+    if (ErrorOut && (Status == EFI_DEVICE_ERROR)) {
+      ASSERT (0);
+    }
+  } while (Status != EFI_NOT_FOUND);
+
+  Status = GenMemoryTest->Finished (GenMemoryTest);
+
+  return EFI_SUCCESS;
+}
-- 
2.34.1



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



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [edk2-devel] [PATCH 0/5] AmdMinBoardPkg: AMD board specific modules
  2024-05-17  3:49 [edk2-devel] [PATCH 0/5] AmdMinBoardPkg: AMD board specific modules Abdul Lateef Attar via groups.io
                   ` (4 preceding siblings ...)
  2024-05-17  3:49 ` [edk2-devel] [PATCH 5/5] AmdMinBoardPkg: Implements BoardBdsHookLib library Abdul Lateef Attar via groups.io
@ 2024-05-17  5:53 ` Chang, Abner via groups.io
  5 siblings, 0 replies; 7+ messages in thread
From: Chang, Abner via groups.io @ 2024-05-17  5:53 UTC (permalink / raw)
  To: devel@edk2.groups.io, Attar, AbdulLateef (Abdul Lateef); +Cc: Grimes, Paul

[AMD Official Use Only - AMD Internal Distribution Only]

Already reviewed internally.
Reviewed-by: Abner Chang <abner.chang@amd.com>

Hi Abdul, please add the tag [edk2-platforms] in subject next time when send the patch for edk2-platforms changes.
Thanks
Abner

> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Abdul
> Lateef Attar via groups.io
> Sent: Friday, May 17, 2024 11:49 AM
> To: devel@edk2.groups.io
> Cc: Attar, AbdulLateef (Abdul Lateef) <AbdulLateef.Attar@amd.com>; Chang,
> Abner <Abner.Chang@amd.com>; Grimes, Paul <Paul.Grimes@amd.com>
> Subject: [edk2-devel] [PATCH 0/5] AmdMinBoardPkg: AMD board specific
> modules
>
> Caution: This message originated from an External Source. Use proper caution
> when opening attachments, clicking links, or responding.
>
>
> PR: https://github.com/tianocore/edk2-platforms/pull/143
> Adds various module common to AMD boards.
> Cc: Abner Chang <abner.chang@amd.com>
> Cc: Paul Grimes <paul.grimes@amd.com>
>
> Abdul Lateef Attar (5):
>   AmdMinBoardPkg: Uncrustify PciHotPlug module
>   AmdMinBoardPkg/Library: Uncrustify the Library module
>   AmdMinBoardPkg: Implement BoardInitLib for PEI phase
>   AmdMinBoardPkg: Implement BoardInitLib for DXE phase
>   AmdMinBoardPkg: Implements BoardBdsHookLib library
>
>  .../AMD/AmdMinBoardPkg/AmdMinBoardPkg.dec     |   10 +
>  .../AMD/AmdMinBoardPkg/AmdMinBoardPkg.dsc     |   10 +-
>  .../Include/Library/AmdBoardBdsHookLib.h      |  130 ++
>  .../Library/BoardBdsHookLib/BoardBdsHook.h    |  242 +++
>  .../Library/BoardBdsHookLib/BoardBdsHookLib.c | 1712
> +++++++++++++++++
>  .../BoardBdsHookLib/BoardBdsHookLib.inf       |  105 +
>  .../Library/BoardBdsHookLib/BoardBootOption.c |  754 ++++++++
>  .../Library/BoardBdsHookLib/BoardMemoryTest.c |   83 +
>  .../Library/DxeBoardInitLib/DxeBoardInitLib.c |  253 +++
>  .../DxeBoardInitLib/DxeBoardInitLib.inf       |   51 +
>  .../DxeBoardInitLib/DxeBoardInitLibInternal.c |  306 +++
>  .../DxeBoardInitLib/DxeBoardInitLibInternal.h |  159 ++
>  .../DxeBoardInitLib/MadtAcpiTablePatch.c      |  243 +++
>  .../PeiBoardInitPreMemLib/AmdMemoryInfoHob.h  |   50 +
>  .../PeiBoardInitPreMemLib.c                   |  229 +++
>  .../PeiBoardInitPreMemLib.inf                 |   45 +
>  .../PeiBoardInitPreMemLib/PeiMemoryInit.c     |  198 ++
>  .../PeiBoardInitPreMemLib/PeiMemoryInit.h     |   50 +
>  .../Library/PeiReportFvLib/PeiReportFvLib.c   |   12 +-
>  .../Library/SetCacheMtrrLib/SetCacheMtrrLib.c |    3 +-
>  .../PciHotPlug/PciHotPlugInit.c               |    4 +-
>  .../PciHotPlug/PciHotPlugInit.inf             |    5 +-
>  22 files changed, 4647 insertions(+), 7 deletions(-)
>  create mode 100644
> Platform/AMD/AmdMinBoardPkg/Include/Library/AmdBoardBdsHookLib.h
>  create mode 100644
> Platform/AMD/AmdMinBoardPkg/Library/BoardBdsHookLib/BoardBdsHook.
> h
>  create mode 100644
> Platform/AMD/AmdMinBoardPkg/Library/BoardBdsHookLib/BoardBdsHookLi
> b.c
>  create mode 100644
> Platform/AMD/AmdMinBoardPkg/Library/BoardBdsHookLib/BoardBdsHookLi
> b.inf
>  create mode 100644
> Platform/AMD/AmdMinBoardPkg/Library/BoardBdsHookLib/BoardBootOptio
> n.c
>  create mode 100644
> Platform/AMD/AmdMinBoardPkg/Library/BoardBdsHookLib/BoardMemoryT
> est.c
>  create mode 100644
> Platform/AMD/AmdMinBoardPkg/Library/DxeBoardInitLib/DxeBoardInitLib.c
>  create mode 100644
> Platform/AMD/AmdMinBoardPkg/Library/DxeBoardInitLib/DxeBoardInitLib.in
> f
>  create mode 100644
> Platform/AMD/AmdMinBoardPkg/Library/DxeBoardInitLib/DxeBoardInitLibIn
> ternal.c
>  create mode 100644
> Platform/AMD/AmdMinBoardPkg/Library/DxeBoardInitLib/DxeBoardInitLibIn
> ternal.h
>  create mode 100644
> Platform/AMD/AmdMinBoardPkg/Library/DxeBoardInitLib/MadtAcpiTablePat
> ch.c
>  create mode 100644
> Platform/AMD/AmdMinBoardPkg/Library/PeiBoardInitPreMemLib/AmdMem
> oryInfoHob.h
>  create mode 100644
> Platform/AMD/AmdMinBoardPkg/Library/PeiBoardInitPreMemLib/PeiBoardI
> nitPreMemLib.c
>  create mode 100644
> Platform/AMD/AmdMinBoardPkg/Library/PeiBoardInitPreMemLib/PeiBoardI
> nitPreMemLib.inf
>  create mode 100644
> Platform/AMD/AmdMinBoardPkg/Library/PeiBoardInitPreMemLib/PeiMemor
> yInit.c
>  create mode 100644
> Platform/AMD/AmdMinBoardPkg/Library/PeiBoardInitPreMemLib/PeiMemor
> yInit.h
>
> --
> 2.34.1
>
>
>
> 
>



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



^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2024-05-17  5:53 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-05-17  3:49 [edk2-devel] [PATCH 0/5] AmdMinBoardPkg: AMD board specific modules Abdul Lateef Attar via groups.io
2024-05-17  3:49 ` [edk2-devel] [PATCH 1/5] AmdMinBoardPkg: Uncrustify PciHotPlug module Abdul Lateef Attar via groups.io
2024-05-17  3:49 ` [edk2-devel] [PATCH 2/5] AmdMinBoardPkg/Library: Uncrustify the Library module Abdul Lateef Attar via groups.io
2024-05-17  3:49 ` [edk2-devel] [PATCH 3/5] AmdMinBoardPkg: Implement BoardInitLib for PEI phase Abdul Lateef Attar via groups.io
2024-05-17  3:49 ` [edk2-devel] [PATCH 4/5] AmdMinBoardPkg: Implement BoardInitLib for DXE phase Abdul Lateef Attar via groups.io
2024-05-17  3:49 ` [edk2-devel] [PATCH 5/5] AmdMinBoardPkg: Implements BoardBdsHookLib library Abdul Lateef Attar via groups.io
2024-05-17  5:53 ` [edk2-devel] [PATCH 0/5] AmdMinBoardPkg: AMD board specific modules Chang, Abner via groups.io

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox