Adds the following modules:
- Library/DxeSaPolicyLib
- SaInit

Cc: Sai Chaganty <rangasai.v.chaga...@intel.com>
Cc: Nate DeSimone <nathaniel.l.desim...@intel.com>
Cc: Isaac Oram <isaac.w.o...@intel.com>
Cc: Rosen Chuang <rosen.chu...@intel.com>
Signed-off-by: Saloni Kasbekar <saloni.kasbe...@intel.com>
---
 .../Library/DxeSaPolicyLib/DxeSaPolicyLib.c   | 225 ++++++++++++++++++
 .../Library/DxeSaPolicyLib/DxeSaPolicyLib.inf |  46 ++++
 .../DxeSaPolicyLib/DxeSaPolicyLibrary.h       |  30 +++
 .../SystemAgent/SaInit/Dxe/SaAcpi.c           | 193 +++++++++++++++
 .../SystemAgent/SaInit/Dxe/SaInit.c           |  97 ++++++++
 .../SystemAgent/SaInit/Dxe/SaInit.h           |  42 ++++
 .../SystemAgent/SaInit/Dxe/SaInitDxe.c        |  90 +++++++
 .../SystemAgent/SaInit/Dxe/SaInitDxe.h        | 119 +++++++++
 .../SystemAgent/SaInit/Dxe/SaInitDxe.inf      |  98 ++++++++
 9 files changed, 940 insertions(+)
 create mode 100644 
Silicon/Intel/AlderlakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLib.c
 create mode 100644 
Silicon/Intel/AlderlakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLib.inf
 create mode 100644 
Silicon/Intel/AlderlakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLibrary.h
 create mode 100644 
Silicon/Intel/AlderlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaAcpi.c
 create mode 100644 
Silicon/Intel/AlderlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.c
 create mode 100644 
Silicon/Intel/AlderlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.h
 create mode 100644 
Silicon/Intel/AlderlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.c
 create mode 100644 
Silicon/Intel/AlderlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.h
 create mode 100644 
Silicon/Intel/AlderlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.inf

diff --git 
a/Silicon/Intel/AlderlakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLib.c
 
b/Silicon/Intel/AlderlakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLib.c
new file mode 100644
index 0000000000..d812f300c1
--- /dev/null
+++ 
b/Silicon/Intel/AlderlakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLib.c
@@ -0,0 +1,225 @@
+/** @file
+  This file provide services for DXE phase policy default initialization
+
+   Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+   SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "DxeSaPolicyLibrary.h"
+#include <Library/DxeGraphicsPolicyLib.h>
+#include <Register/SaRegsHostBridge.h>
+#include "MemoryConfig.h"
+
+extern EFI_GUID gMemoryDxeConfigGuid;
+
+/**
+  This function prints the SA DXE phase policy.
+
+  @param[in] SaPolicy - SA DXE Policy protocol
+**/
+VOID
+SaPrintPolicyProtocol (
+  IN  SA_POLICY_PROTOCOL      *SaPolicy
+  )
+{
+  UINT8                       ControllerIndex;
+  UINT8                       ChannelIndex;
+  EFI_STATUS                  Status;
+  MEMORY_DXE_CONFIG           *MemoryDxeConfig;
+
+  Status = GetConfigBlock ((VOID *) SaPolicy, &gMemoryDxeConfigGuid, (VOID 
*)&MemoryDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+
+
+  DEBUG_CODE_BEGIN ();
+  INTN  i;
+
+  DEBUG ((DEBUG_INFO, "\n------------------------ SA Policy (DXE) print BEGIN 
-----------------\n"));
+  DEBUG ((DEBUG_INFO, "Revision : %x\n", 
SaPolicy->TableHeader.Header.Revision));
+  ASSERT (SaPolicy->TableHeader.Header.Revision == 
SA_POLICY_PROTOCOL_REVISION);
+
+  DEBUG ((DEBUG_INFO, "------------------------ SA_MEMORY_CONFIGURATION 
-----------------\n"));
+
+  DEBUG ((DEBUG_INFO, " SpdAddressTable[%d] :", 4));
+  for (i = 0; i < 4; i++) {
+    DEBUG ((DEBUG_INFO, " %x", MemoryDxeConfig->SpdAddressTable[i]));
+  }
+  DEBUG ((DEBUG_INFO, "\n"));
+
+  for (ControllerIndex = 0; ControllerIndex < MEM_CFG_MAX_CONTROLLERS; 
ControllerIndex++) {
+    for (ChannelIndex = 0; ChannelIndex < MEM_CFG_MAX_CHANNELS; 
ChannelIndex++) {
+      DEBUG ((DEBUG_INFO, " SlotMap[%d][%d] : 0x%x\n", ControllerIndex, 
ChannelIndex, MemoryDxeConfig->SlotMap[ControllerIndex][ChannelIndex]));
+    }
+  }
+  DEBUG ((DEBUG_INFO, " MrcTimeMeasure  : %x\n", 
MemoryDxeConfig->MrcTimeMeasure));
+  DEBUG ((DEBUG_INFO, " MrcFastBoot     : %x\n", 
MemoryDxeConfig->MrcFastBoot));
+
+  DEBUG ((DEBUG_INFO, "------------------------ CPU_PCIE_CONFIGURATION 
-----------------\n"));
+  DEBUG ((DEBUG_INFO, " PegAspm[%d] :", SA_PEG_MAX_FUN));
+  DEBUG ((DEBUG_INFO, " PegRootPortHPE[%d] :", SA_PEG_MAX_FUN));
+  DEBUG ((DEBUG_INFO, "\n"));
+
+
+  DEBUG ((DEBUG_INFO, "\n------------------------ SA Policy (DXE) print END 
-----------------\n"));
+  DEBUG_CODE_END ();
+
+  return;
+}
+
+/**
+  Load DXE Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadMemoryDxeDefault (
+  IN VOID    *ConfigBlockPointer
+  )
+{
+  UINT8                    ControllerIndex;
+  UINT8                    ChannelIndex;
+  MEMORY_DXE_CONFIG        *MemoryDxeConfig;
+
+  MemoryDxeConfig = ConfigBlockPointer;
+  ///
+  /// Initialize the Memory Configuration
+  ///
+  ///
+  /// DIMM SMBus addresses info
+  /// Refer to the SpdAddressTable[] mapping rule in DxeSaPolicyLibrary.h
+  ///
+  MemoryDxeConfig->SpdAddressTable = AllocateZeroPool (sizeof (UINT8) * 4);
+  ASSERT (MemoryDxeConfig->SpdAddressTable != NULL);
+  if (MemoryDxeConfig->SpdAddressTable != NULL) {
+    MemoryDxeConfig->SpdAddressTable[0] = DIMM_SMB_SPD_P0C0D0;
+    MemoryDxeConfig->SpdAddressTable[1] = DIMM_SMB_SPD_P0C0D1;
+    MemoryDxeConfig->SpdAddressTable[2] = DIMM_SMB_SPD_P0C1D0;
+    MemoryDxeConfig->SpdAddressTable[3] = DIMM_SMB_SPD_P0C1D1;
+  }
+  MemoryDxeConfig->SlotMap = (UINT8**)AllocateZeroPool (sizeof (UINT8*) * 
MEM_CFG_MAX_CONTROLLERS);
+  ASSERT (MemoryDxeConfig->SlotMap != NULL);
+  if (MemoryDxeConfig->SlotMap != NULL) {
+    for (ControllerIndex = 0; ControllerIndex < MEM_CFG_MAX_CONTROLLERS; 
ControllerIndex++) {
+      MemoryDxeConfig->SlotMap[ControllerIndex] = (UINT8*)AllocateZeroPool 
(sizeof (UINT8) * MEM_CFG_MAX_CHANNELS);
+      ASSERT (MemoryDxeConfig->SlotMap[ControllerIndex] != NULL);
+      if (MemoryDxeConfig->SlotMap[ControllerIndex] != NULL) {
+        for (ChannelIndex = 0; ChannelIndex < MEM_CFG_MAX_CHANNELS; 
ChannelIndex++) {
+          MemoryDxeConfig->SlotMap[ControllerIndex][ChannelIndex] = 0x01;
+        }
+      }
+    }
+  }
+}
+
+/**
+  LoadSaDxeConfigBlockDefault - Initialize default settings for each SA Config 
block
+
+  @param[in] ConfigBlockPointer         The buffer pointer that will be 
initialized as specific config block
+  @param[in] BlockId                    Request to initialize defaults of 
specified config block by given Block ID
+
+  @retval EFI_SUCCESS                   The given buffer has contained the 
defaults of requested config block
+  @retval EFI_NOT_FOUND                 Block ID is not defined so no default 
Config block will be initialized
+**/
+
+GLOBAL_REMOVE_IF_UNREFERENCED COMPONENT_BLOCK_ENTRY  mSaDxeIpBlocks [] = {
+  {&gMemoryDxeConfigGuid,   sizeof (MEMORY_DXE_CONFIG),   
MEMORY_DXE_CONFIG_REVISION,    LoadMemoryDxeDefault}
+};
+
+
+/**
+  CreateSaDxeConfigBlocks generates the config blocksg of SA DXE Policy.
+  It allocates and zero out buffer, and fills in the Intel default settings.
+
+  @param[out] SaPolicy               The pointer to get SA  DXE Protocol 
instance
+
+  @retval EFI_SUCCESS                   The policy default is initialized.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+CreateSaDxeConfigBlocks (
+  IN OUT  SA_POLICY_PROTOCOL      **SaPolicy
+  )
+{
+  UINT16              TotalBlockSize;
+  EFI_STATUS          Status;
+  SA_POLICY_PROTOCOL  *SaInitPolicy;
+  UINT16              RequiredSize;
+
+  DEBUG ((DEBUG_INFO, "SA Create Dxe Config Blocks\n"));
+
+  SaInitPolicy = NULL;
+
+  TotalBlockSize = GetComponentConfigBlockTotalSize (&mSaDxeIpBlocks[0], 
sizeof (mSaDxeIpBlocks) / sizeof (COMPONENT_BLOCK_ENTRY));
+  TotalBlockSize += GraphicsGetConfigBlockTotalSizeDxe ();
+  DEBUG ((DEBUG_INFO, "TotalBlockSize = 0x%x\n", TotalBlockSize));
+
+  RequiredSize = sizeof (CONFIG_BLOCK_TABLE_HEADER) + TotalBlockSize;
+
+  Status = CreateConfigBlockTable (RequiredSize, (VOID *) &SaInitPolicy);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Initialize Policy Revision
+  //
+  SaInitPolicy->TableHeader.Header.Revision = SA_POLICY_PROTOCOL_REVISION;
+  //
+  // Add config blocks.
+  //
+  Status =  AddComponentConfigBlocks ((VOID *) SaInitPolicy, 
&mSaDxeIpBlocks[0], sizeof (mSaDxeIpBlocks) / sizeof (COMPONENT_BLOCK_ENTRY));
+  ASSERT_EFI_ERROR (Status);
+
+
+  // Gfx
+  Status = GraphicsAddConfigBlocksDxe ((VOID *) SaInitPolicy);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Assignment for returning SaInitPolicy config block base address
+  //
+  *SaPolicy = SaInitPolicy;
+  return Status;
+}
+
+
+/**
+  SaInstallPolicyProtocol installs SA Policy.
+  While installed, RC assumes the Policy is ready and finalized. So please 
update and override
+  any setting before calling this function.
+
+  @param[in] ImageHandle                Image handle of this driver.
+  @param[in] SaPolicy                   The pointer to SA Policy Protocol 
instance
+
+  @retval EFI_SUCCESS                   The policy is installed.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+
+**/
+EFI_STATUS
+EFIAPI
+SaInstallPolicyProtocol (
+  IN  EFI_HANDLE                  ImageHandle,
+  IN  SA_POLICY_PROTOCOL         *SaPolicy
+  )
+{
+  EFI_STATUS            Status;
+
+  ///
+  /// Print SA DXE Policy
+  ///
+  SaPrintPolicyProtocol (SaPolicy);
+  GraphicsDxePolicyPrint (SaPolicy);
+
+  ///
+  /// Install protocol to to allow access to this Policy.
+  ///
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &ImageHandle,
+                  &gSaPolicyProtocolGuid,
+                  SaPolicy,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
diff --git 
a/Silicon/Intel/AlderlakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLib.inf
 
b/Silicon/Intel/AlderlakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLib.inf
new file mode 100644
index 0000000000..02d52b6e6b
--- /dev/null
+++ 
b/Silicon/Intel/AlderlakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLib.inf
@@ -0,0 +1,46 @@
+## @file
+# Component description file for the PeiSaPolicy library.
+#
+#   Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+#   SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = DxeSaPolicyLib
+FILE_GUID = B402A3A4-4B82-410E-B79C-5914880A05E7
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = DxeSaPolicyLib
+
+
+[LibraryClasses]
+BaseMemoryLib
+UefiRuntimeServicesTableLib
+UefiBootServicesTableLib
+DebugLib
+PostCodeLib
+ConfigBlockLib
+HobLib
+DxeGraphicsPolicyLib
+CpuPlatformLib
+
+[Packages]
+MdePkg/MdePkg.dec
+AlderlakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+DxeSaPolicyLib.c
+DxeSaPolicyLibrary.h
+
+
+[Guids]
+gMemoryDxeConfigGuid
+
+
+[Protocols]
+gSaPolicyProtocolGuid ## PRODUCES
+
+[Pcd]
diff --git 
a/Silicon/Intel/AlderlakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLibrary.h
 
b/Silicon/Intel/AlderlakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLibrary.h
new file mode 100644
index 0000000000..14fc02512e
--- /dev/null
+++ 
b/Silicon/Intel/AlderlakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLibrary.h
@@ -0,0 +1,30 @@
+/** @file
+  Header file for the DxeSaPolicy library.
+
+   Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+   SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _DXE_SA_POLICY_LIBRARY_H_
+#define _DXE_SA_POLICY_LIBRARY_H_
+
+#include <Uefi.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/ConfigBlockLib.h>
+#include <CpuPcieConfigGen3.h>
+#include <CpuPcieConfig.h>
+#include <Protocol/SaPolicy.h>
+
+#define WORD_FIELD_VALID_BIT  BIT15
+///
+/// DIMM SMBus addresses
+///
+#define DIMM_SMB_SPD_P0C0D0 0xA0
+#define DIMM_SMB_SPD_P0C0D1 0xA2
+#define DIMM_SMB_SPD_P0C1D0 0xA4
+#define DIMM_SMB_SPD_P0C1D1 0xA6
+
+#endif // _DXE_SA_POLICY_LIBRARY_H_
diff --git a/Silicon/Intel/AlderlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaAcpi.c 
b/Silicon/Intel/AlderlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaAcpi.c
new file mode 100644
index 0000000000..f73995be0c
--- /dev/null
+++ b/Silicon/Intel/AlderlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaAcpi.c
@@ -0,0 +1,193 @@
+/** @file
+  This is the driver that initializes the Intel System Agent.
+
+   Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+   SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include "SaInitDxe.h"
+#include "SaInit.h"
+#include <Protocol/SaNvsArea.h>
+#include <Library/PchInfoLib.h>
+#include <CpuPcieInfo.h>
+#include <Library/AslUpdateLib.h>
+#include <HostBridgeDataHob.h>
+#include <Library/CpuPlatformLib.h>
+#include <Library/PeiDxeSmmReserveMmio64SizeLib.h>
+#include <Register/Cpuid.h>
+#include <Protocol/FirmwareVolume2.h>
+#include <Pi/PiFirmwareFile.h>
+
+///
+/// Global Variables
+///
+GLOBAL_REMOVE_IF_UNREFERENCED SYSTEM_AGENT_NVS_AREA_PROTOCOL  
mSaNvsAreaProtocol;
+
+/**
+  A protocol callback which updates 64bits MMIO Base and Length in SA GNVS area
+**/
+VOID
+UpdateSaGnvsForMmioResourceBaseLength (
+  VOID
+  )
+{
+  EFI_PHYSICAL_ADDRESS      PciBaseAddress;
+  UINT32                    Tolud;
+  UINT64                    Length;
+  UINT64                    McD0BaseAddress;
+  UINTN                     ResMemLimit1;
+  BOOLEAN                   EnableAbove4GBMmioBiosAssignemnt;
+  VOID                      *CpuHob;
+  UINT8                     PhysicalAddressBits;
+  UINT64                    PhysicalAddressLimit;
+
+  PciBaseAddress                   = 0;
+  Tolud                            = 0;
+  Length                           = 0;
+  ResMemLimit1                     = 0;
+  EnableAbove4GBMmioBiosAssignemnt = TRUE;
+  CpuHob                           = NULL;
+  PhysicalAddressBits              = 0;
+  PhysicalAddressLimit             = 0;
+  //
+  // Read memory map registers
+  //
+  McD0BaseAddress        = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, 0, 
0, 0);
+  Tolud                  = PciSegmentRead32 (McD0BaseAddress + R_SA_TOLUD) & 
B_SA_TOLUD_TOLUD_MASK;
+  PciBaseAddress         = Tolud;
+
+  ResMemLimit1 = (UINTN) PcdGet64 (PcdSiPciExpressBaseAddress);
+
+  Length = ResMemLimit1 - PciBaseAddress;
+
+  CpuHob = GetFirstHob (EFI_HOB_TYPE_CPU);
+  if (CpuHob != NULL) {
+    PhysicalAddressBits  = ((EFI_HOB_CPU *) CpuHob)->SizeOfMemorySpace;
+    PhysicalAddressLimit = LShiftU64 (1, PhysicalAddressBits);
+  }
+  //
+  // Check Enable Above 4GB MMIO or not
+  //
+
+  DEBUG ((DEBUG_INFO, "Update SA GNVS Area.\n"));
+  mSaNvsAreaProtocol.Area->Mmio32Base   = (UINT32) PciBaseAddress;
+  mSaNvsAreaProtocol.Area->Mmio32Length = (UINT32) Length;
+  if (EnableAbove4GBMmioBiosAssignemnt == TRUE) {
+    if (PhysicalAddressBits != 0 && ( PhysicalAddressLimit % 0x4000000000) == 
0) { // Checking Memory Size multiples of 256GB
+      mSaNvsAreaProtocol.Area->Mmio64Base   = BASE_256GB;
+      //
+      // Some platforms need to reserve MMIO space from PhysicalAddressLimit 
for P2SB usage.
+      //
+      mSaNvsAreaProtocol.Area->Mmio64Length = PhysicalAddressLimit - 
mSaNvsAreaProtocol.Area->Mmio64Base - ReserveMmio64Size ();
+    } else {
+      mSaNvsAreaProtocol.Area->Mmio64Base   = BASE_256GB;
+      mSaNvsAreaProtocol.Area->Mmio64Length = SIZE_256GB;
+    }
+  }
+  DEBUG ((DEBUG_INFO, "SaNvsAreaProtocol.Area->Mmio64Base = %lx\n", 
mSaNvsAreaProtocol.Area->Mmio64Base));
+  DEBUG ((DEBUG_INFO, "SaNvsAreaProtocol.Area->Mmio64Length = %lx\n", 
mSaNvsAreaProtocol.Area->Mmio64Length));
+  DEBUG ((DEBUG_INFO, "SaNvsAreaProtocol.Area->Mmio32Base = %lx\n", 
mSaNvsAreaProtocol.Area->Mmio32Base));
+  DEBUG ((DEBUG_INFO, "SaNvsAreaProtocol.Area->Mmio32Length = %lx\n", 
mSaNvsAreaProtocol.Area->Mmio32Length));
+}
+
+/**
+  Initialize SA Nvs Area operation region.
+
+  @retval EFI_SUCCESS    initialized successfully
+  @retval EFI_NOT_FOUND  Nvs Area operation region is not found
+**/
+EFI_STATUS
+PatchSaNvsAreaAddress (
+  VOID
+  )
+{
+  EFI_STATUS                            Status;
+  UINT32                                Address;
+  UINT16                                Length;
+
+  Address = (UINT32) (UINTN) mSaNvsAreaProtocol.Area;
+  Length  = (UINT16) sizeof (SYSTEM_AGENT_NVS_AREA);
+  DEBUG ((DEBUG_INFO, "PatchSaNvsAreaAddress: SA NVS Address %x Length %x\n", 
Address, Length));
+
+  Status  = UpdateNameAslCode (SIGNATURE_32 ('S','A','N','B'), &Address, 
sizeof (Address));
+  ASSERT_EFI_ERROR (Status);
+  Status  = UpdateNameAslCode (SIGNATURE_32 ('S','A','N','L'), &Length, sizeof 
(Length));
+  ASSERT_EFI_ERROR (Status);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This function gets registered as a callback to perform Dmar Igd
+
+  @param[in] Event     - A pointer to the Event that triggered the callback.
+  @param[in] Context   - A pointer to private data registered with the 
callback function.
+**/
+VOID
+EFIAPI
+SaAcpiEndOfDxeCallback (
+  IN EFI_EVENT    Event,
+  IN VOID         *Context
+  )
+{
+
+  DEBUG ((DEBUG_INFO, "%a - Start\n", __FUNCTION__));
+
+  PatchSaNvsAreaAddress();
+
+  DEBUG ((DEBUG_INFO, "%a - End\n", __FUNCTION__));
+  return;
+}
+
+
+/**
+  SystemAgent Acpi Initialization.
+
+  @param[in] ImageHandle             Handle for the image of this driver
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_OUT_OF_RESOURCES    No enough buffer to allocate
+**/
+EFI_STATUS
+EFIAPI
+SaAcpiInit (
+  IN EFI_HANDLE         ImageHandle
+  )
+{
+  EFI_STATUS                Status;
+  EFI_EVENT                 EndOfDxeEvent;
+
+  ///
+  /// Install System Agent Global NVS protocol
+  ///
+  DEBUG ((DEBUG_INFO, "Install SA GNVS protocol\n"));
+  Status = (gBS->AllocatePool) (EfiACPIMemoryNVS, sizeof 
(SYSTEM_AGENT_NVS_AREA), (VOID **) &mSaNvsAreaProtocol.Area);
+  ASSERT_EFI_ERROR (Status);
+  ZeroMem ((VOID *) mSaNvsAreaProtocol.Area, sizeof (SYSTEM_AGENT_NVS_AREA));
+
+
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &ImageHandle,
+                  &gSaNvsAreaProtocolGuid,
+                  &mSaNvsAreaProtocol,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+
+  ///
+  /// Register an end of DXE event for SA ACPI to do tasks before invoking any 
UEFI drivers,
+  /// applications, or connecting consoles,...
+  ///
+  
+  Status = gBS->CreateEventEx (
+                  EVT_NOTIFY_SIGNAL,
+                  TPL_CALLBACK,
+                  SaAcpiEndOfDxeCallback,
+                  NULL,
+                  &gEfiEndOfDxeEventGroupGuid,
+                  &EndOfDxeEvent
+                  );
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Silicon/Intel/AlderlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.c 
b/Silicon/Intel/AlderlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.c
new file mode 100644
index 0000000000..5e472b0f60
--- /dev/null
+++ b/Silicon/Intel/AlderlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.c
@@ -0,0 +1,97 @@
+/** @file
+  This is the Common driver that initializes the Intel System Agent.
+
+   Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+   SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include "SaInit.h"
+#include <Library/PciSegmentLib.h>
+#include <HostBridgeDataHob.h>
+#include <Protocol/PciEnumerationComplete.h>
+#include <Library/CpuPlatformLib.h>
+#include <Register/SaRegsHostBridge.h>
+
+///
+/// Global Variables
+///
+BOOLEAN                                                              
mSkipPamLock = FALSE;
+
+/*
+  Intel(R) Core Processor Skylake BWG version 0.4.0
+
+  18.6 System Agent Configuration Locking
+   For reliable operation and security, System BIOS must set the following 
bits:
+   1. For all modern Intel processors, Intel strongly recommends that BIOS 
should set
+       the D_LCK bit. Set B0:D0:F0.R088h [4] = 1b to lock down SMRAM space.
+  BaseAddr values for mSaSecurityRegisters that uses PciExpressBaseAddress 
will be initialized at
+  Runtime inside function CpuPcieInitPolicy().
+*/
+GLOBAL_REMOVE_IF_UNREFERENCED BOOT_SCRIPT_REGISTER_SETTING 
mSaSecurityRegisters[] = {
+  {0,  R_SA_SMRAMC,  0xFFFFFFFF,  BIT4}
+};
+
+/**
+  SystemAgent Initialization Common Function.
+
+  @retval EFI_SUCCESS   - Always.
+**/
+
+VOID
+SaInitEntryPoint (
+  VOID
+  )
+{
+  HOST_BRIDGE_DATA_HOB        *HostBridgeDataHob;
+
+  ///
+  /// Get Host Bridge Data HOB
+  ///
+  HostBridgeDataHob = NULL;
+  HostBridgeDataHob = (HOST_BRIDGE_DATA_HOB *) GetFirstGuidHob 
(&gHostBridgeDataHobGuid);
+  if (HostBridgeDataHob != NULL) {
+    mSkipPamLock = HostBridgeDataHob->SkipPamLock;
+  }
+  return;
+}
+
+/**
+  This function does SA security lock
+**/
+VOID
+SaSecurityLock (
+  VOID
+  )
+{
+  UINT8           Index;
+  UINT64          BaseAddress;
+  UINT32          RegOffset;
+  UINT32          Data32And;
+  UINT32          Data32Or;
+
+  ///
+  /// 17.2 System Agent Security Lock configuration
+  ///
+  DEBUG ((DEBUG_INFO, "DXE SaSecurityLock\n"));
+  for (Index = 0; Index < (sizeof (mSaSecurityRegisters) / sizeof 
(BOOT_SCRIPT_REGISTER_SETTING)); Index++) {
+    BaseAddress = mSaSecurityRegisters[Index].BaseAddr;
+    RegOffset   = mSaSecurityRegisters[Index].Offset;
+    Data32And   = mSaSecurityRegisters[Index].AndMask;
+    Data32Or    = mSaSecurityRegisters[Index].OrMask;
+
+    if (RegOffset == R_SA_SMRAMC) {
+      ///
+      /// SMRAMC LOCK must use CF8/CFC access
+      ///
+      PciCf8Or8 (PCI_CF8_LIB_ADDRESS (SA_MC_BUS, SA_MC_DEV, SA_MC_FUN, 
R_SA_SMRAMC), (UINT8) Data32Or);
+      BaseAddress = S3_BOOT_SCRIPT_LIB_PCI_ADDRESS (SA_MC_BUS, SA_MC_DEV, 
SA_MC_FUN, R_SA_SMRAMC);
+      S3BootScriptSavePciCfgReadWrite (
+        S3BootScriptWidthUint8,
+        (UINTN) BaseAddress,
+        &Data32Or,
+        &Data32And
+        );
+    }
+  }
+
+}
+
diff --git a/Silicon/Intel/AlderlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.h 
b/Silicon/Intel/AlderlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.h
new file mode 100644
index 0000000000..14e48a3eb4
--- /dev/null
+++ b/Silicon/Intel/AlderlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.h
@@ -0,0 +1,42 @@
+/** @file
+  Header file for SA Common Initialization Driver.
+
+   Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+   SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _SA_INITIALIZATION_DRIVER_H_
+#define _SA_INITIALIZATION_DRIVER_H_
+
+#include <Uefi.h>
+#include <IndustryStandard/Acpi.h>
+#include <IndustryStandard/Pci.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/UefiLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciCf8Lib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/S3BootScriptLib.h>
+#include <Guid/EventGroup.h>
+#include <CpuRegs.h>
+#include <Library/CpuPlatformLib.h>
+#include <Protocol/SaPolicy.h>
+
+typedef struct {
+  UINT64  BaseAddr;
+  UINT32  Offset;
+  UINT32  AndMask;
+  UINT32  OrMask;
+} BOOT_SCRIPT_REGISTER_SETTING;
+
+/**
+  SystemAgent Initialization Common Function.
+
+  @retval EFI_SUCCESS   - Always.
+**/
+VOID
+SaInitEntryPoint (
+  VOID
+  );
+#endif
diff --git 
a/Silicon/Intel/AlderlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.c 
b/Silicon/Intel/AlderlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.c
new file mode 100644
index 0000000000..0e613fce3a
--- /dev/null
+++ b/Silicon/Intel/AlderlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.c
@@ -0,0 +1,90 @@
+/** @file
+  This is the driver that initializes the Intel System Agent.
+
+   Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+   SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include "SaInitDxe.h"
+#include "SaInit.h"
+#include <MemInfoHob.h>
+#include <Protocol/PciEnumerationComplete.h>
+#include <Library/CpuPlatformLib.h>
+#include <Library/CpuPcieInfoFruLib.h>
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINT16                   mPcieIoTrapAddress;
+
+/**
+  SystemAgent Dxe Initialization.
+
+  @param[in] ImageHandle             Handle for the image of this driver
+  @param[in] SystemTable             Pointer to the EFI System Table
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_OUT_OF_RESOURCES    No enough buffer to allocate
+**/
+EFI_STATUS
+EFIAPI
+SaInitEntryPointDxe (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  EFI_STATUS                Status;
+  VOID                      *Registration;
+#if FixedPcdGetBool(PcdFspWrapperEnable) == 0
+  EFI_EVENT                 Event;
+#endif
+
+  DEBUG ((DEBUG_INFO, "SaInitDxe Start\n"));
+
+  SaInitEntryPoint ();
+
+  Status = SaAcpiInit (ImageHandle);
+  ///
+  /// Create PCI Enumeration Completed callback for CPU PCIe
+  ///
+  EfiCreateProtocolNotifyEvent (
+    &gEfiPciEnumerationCompleteProtocolGuid,
+    TPL_CALLBACK,
+    CpuPciEnumCompleteCallback,
+    NULL,
+    &Registration
+    );
+
+  DEBUG ((DEBUG_INFO, "SaInitDxe End\n"));
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This function gets registered as a callback to perform CPU PCIe 
initialization before EndOfDxe
+
+  @param[in] Event     - A pointer to the Event that triggered the callback.
+  @param[in] Context   - A pointer to private data registered with the 
callback function.
+**/
+VOID
+EFIAPI
+CpuPciEnumCompleteCallback (
+  IN EFI_EVENT    Event,
+  IN VOID         *Context
+  )
+{
+  EFI_STATUS          Status;
+  VOID                *ProtocolPointer;
+
+  DEBUG ((DEBUG_INFO, "CpuPciEnumCompleteCallback Start\n"));
+  ///
+  /// 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);
+
+  UpdateSaGnvsForMmioResourceBaseLength ();
+  DEBUG ((DEBUG_INFO, "CpuPciEnumCompleteCallback End\n"));
+  return;
+}
diff --git 
a/Silicon/Intel/AlderlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.h 
b/Silicon/Intel/AlderlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.h
new file mode 100644
index 0000000000..72c0a25493
--- /dev/null
+++ b/Silicon/Intel/AlderlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.h
@@ -0,0 +1,119 @@
+/** @file
+  Header file for SA Initialization Driver.
+
+   Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+   SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _SA_INIT_DXE_DRIVER_H_
+#define _SA_INIT_DXE_DRIVER_H_
+
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/AcpiTable.h>
+#include <Library/DxeIgdOpRegionInitLib.h>
+#include <Library/CpuPlatformLib.h>
+#include <Register/SaRegsHostBridge.h>
+
+///
+/// Driver Consumed Protocol Prototypes
+///
+#include <Protocol/SaPolicy.h>
+
+typedef struct {
+  UINT64                Address;
+  EFI_BOOT_SCRIPT_WIDTH Width;
+  UINT32                Value;
+} BOOT_SCRIPT_PCI_REGISTER_SAVE;
+
+///
+/// Function Prototype
+///
+/**
+  This function gets registered as a callback to perform CPU PCIe 
initialization before ExitPmAuth
+
+  @param[in] Event     - A pointer to the Event that triggered the callback.
+  @param[in] Context   - A pointer to private data registered with the 
callback function.
+
+**/
+VOID
+EFIAPI
+CpuPciEnumCompleteCallback (
+  IN EFI_EVENT Event,
+  IN VOID      *Context
+  );
+
+/**
+  <b>System Agent Initialization DXE Driver Entry Point</b>
+  - <b>Introduction</b> \n
+    Based on the information/data in SA_POLICY_PROTOCOL, this module performs 
further SA initialization in DXE phase,
+    e.g. internal devices enable/disable, SSVID/SID programming, graphic 
power-management, VT-d, IGD OpRegion initialization.
+    From the perspective of a PCI Express hierarchy, the Broadwell System 
Agent and PCH together appear as a Root Complex with root ports the number of 
which depends on how the 8 PCH ports and 4 System Agent PCIe ports are 
configured [4x1, 2x8, 1x16].
+    There is an internal link (DMI or OPI) that connects the System Agent to 
the PCH component. This driver includes initialization of SA DMI, PCI Express, 
SA & PCH Root Complex Topology.
+    For iGFX, this module implements the initialization of the Graphics 
Technology Power Management from the Broadwell System Agent BIOS Specification 
and the initialization of the IGD OpRegion/Software SCI - BIOS Specification.
+    The ASL files that go along with the driver define the IGD OpRegion 
mailboxes in ACPI space and implement the software SCI interrupt mechanism.
+    The IGD OpRegion/Software SCI code serves as a communication interface 
between system BIOS, ASL, and Intel graphics driver including making a block of 
customizable data (VBT) from the Intel video BIOS available.
+    Reference Code for the SCI service functions "Get BIOS Data" and "System 
BIOS Callback" can be found in the ASL files, those functions can be platform 
specific, the sample provided in the reference code are implemented for Intel 
CRB.
+    This module implements the VT-d functionality described in the Broadwell 
System Agent BIOS Specification.
+    This module publishes the LegacyRegion protocol to control the read and 
write accesses to the Legacy BIOS ranges.
+    E000 and F000 segments are the legacy BIOS ranges and contain pointers to 
the ACPI regions, SMBIOS tables and so on. This is a private protocol used by 
Intel Framework.
+    This module registers CallBack function that performs SA security 
registers lockdown at end of post as required from Broadwell Bios Spec.
+    In addition, this module publishes the SaInfo Protocol with information 
such as current System Agent reference code version#.
+
+  - @pre
+    - EFI_FIRMWARE_VOLUME_PROTOCOL: Documented in Firmware Volume 
Specification, available at the URL: 
http://www.intel.com/technology/framework/spec.htm
+    - SA_POLICY_PROTOCOL: A protocol published by a platform DXE module 
executed earlier; this is documented in this document as well.
+    - EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL: Documented in the Unified Extensible 
Firmware Interface Specification, version 2.0, available at the URL: 
http://www.uefi.org/specs/
+    - EFI_BOOT_SCRIPT_SAVE_PROTOCOL: A protocol published by a platform DXE 
module executed earlier; refer to the Sample Code section of the Framework PCH 
Reference Code.
+    - EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL: Documented in the 
Unified Extensible Firmware Interface Specification, version 2.0, available at 
the URL: http://www.uefi.org/specs/
+    - EFI_ACPI_TABLE_PROTOCOL : Documented in PI Specification 1.2
+    - EFI_CPU_IO_PROTOCOL: Documented in CPU I/O Protocol Specification, 
available at the URL: http://www.intel.com/technology/framework/spec.htm
+    - EFI_DATA_HUB_PROTOCOL: Documented in EFI Data Hub Infrastructure 
Specification, available at the URL: 
http://www.intel.com/technology/framework/spec.htm
+    - EFI_HII_PROTOCOL (or EFI_HII_DATABASE_PROTOCOL for UEFI 2.1): Documented 
in Human Interface Infrastructure Specification, available at the URL: 
http://www.intel.com/technology/framework/spec.htm
+    (For EFI_HII_DATABASE_PROTOCOL, refer to UEFI Specification Version 2.1 
available at the URL: http://www.uefi.org/)
+
+  - @result
+    IGD power-management functionality is initialized;  VT-d is initialized 
(meanwhile, the DMAR table is updated); IGD OpRegion is initialized - 
IGD_OPREGION_PROTOCOL installed, IGD OpRegion allocated and mailboxes 
initialized, chipset initialized and ready to generate Software SCI for 
Internal graphics events. Publishes the SA_INFO_PROTOCOL with current SA 
reference code version #. Publishes the EFI_LEGACY_REGION_PROTOCOL documented 
in the Compatibility Support Module Specification, version 0.9, available at 
the URL: http://www.intel.com/technology/framework/spec.htm
+
+  - <b>References</b> \n
+    IGD OpRegion/Software SCI for Broadwell
+    Advanced Configuration and Power Interface Specification Revision 4.0a.
+
+  - <b>Porting Recommendations</b> \n
+    No modification of the DXE driver should be typically necessary.
+    This driver should be executed after all related devices (audio, video, 
ME, etc.) are initialized to ensure correct data in DMAR table and 
DMA-remapping registers.
+
+  @param[in] ImageHandle             Handle for the image of this driver
+  @param[in] SystemTable             Pointer to the EFI System Table
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_OUT_OF_RESOURCES    No enough buffer to allocate
+**/
+EFI_STATUS
+EFIAPI
+SaInitEntryPointDxe (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  );
+
+/**
+  SystemAgent Acpi Initialization.
+
+  @param[in] ImageHandle             Handle for the image of this driver
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_OUT_OF_RESOURCES    No enough buffer to allocate
+**/
+EFI_STATUS
+EFIAPI
+SaAcpiInit (
+  IN EFI_HANDLE         ImageHandle
+  );
+
+/**
+  A protocol callback which updates 64bits MMIO Base and Length in SA GNVS area
+**/
+VOID
+UpdateSaGnvsForMmioResourceBaseLength (
+  VOID
+  );
+
+#endif
diff --git 
a/Silicon/Intel/AlderlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.inf 
b/Silicon/Intel/AlderlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.inf
new file mode 100644
index 0000000000..b434ce9027
--- /dev/null
+++ b/Silicon/Intel/AlderlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.inf
@@ -0,0 +1,98 @@
+## @file
+# Component description file for SystemAgent Initialization driver
+#
+#   Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+#   SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = SaInitDxe
+FILE_GUID = DE23ACEE-CF55-4fb6-AA77-984AB53DE811
+VERSION_STRING = 1.0
+MODULE_TYPE = DXE_DRIVER
+ENTRY_POINT = SaInitEntryPointDxe
+#
+# The following information is for reference only and not required by the 
build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+
+
+
+[LibraryClasses]
+UefiDriverEntryPoint
+UefiLib
+UefiBootServicesTableLib
+DxeServicesTableLib
+DebugLib
+TimerLib
+PciCf8Lib
+PciSegmentLib
+BaseMemoryLib
+MemoryAllocationLib
+CpuPlatformLib
+IoLib
+S3BootScriptLib
+PmcLib
+PchCycleDecodingLib
+PchInfoLib
+GpioLib
+ConfigBlockLib
+PchPcieRpLib
+DxeIgdOpRegionInitLib
+AslUpdateLib
+PeiDxeSmmReserveMmio64SizeLib
+CpuPcieInfoFruLib
+
+[Packages]
+MdePkg/MdePkg.dec
+UefiCpuPkg/UefiCpuPkg.dec
+IntelSiliconPkg/IntelSiliconPkg.dec
+AlderlakeSiliconPkg/SiPkg.dec
+
+[Pcd]
+gSiPkgTokenSpaceGuid.PcdSiPciExpressBaseAddress
+gSiPkgTokenSpaceGuid.PcdMchBaseAddress
+gSiPkgTokenSpaceGuid.PcdSiIoApicBaseAddress
+gSiPkgTokenSpaceGuid.PcdFspWrapperEnable
+gSiPkgTokenSpaceGuid.PcdCpuPcieEnable                  ## CONSUMES
+
+[FixedPcd]
+gSiPkgTokenSpaceGuid.PcdAdlLpSupport               ## CONSUMES
+gSiPkgTokenSpaceGuid.PcdAdlSSupport
+
+[Sources]
+SaInitDxe.h
+SaInitDxe.c
+SaInit.h
+SaInit.c
+SaAcpi.c
+
+[Protocols]
+gEfiAcpiTableProtocolGuid              ## CONSUMES
+gSaNvsAreaProtocolGuid                 ## PRODUCES
+gSaPolicyProtocolGuid                  ## CONSUMES
+gEfiCpuArchProtocolGuid                ## CONSUMES
+gEfiPciEnumerationCompleteProtocolGuid ## CONSUMES
+gEfiPciRootBridgeIoProtocolGuid        ## CONSUMES
+gIgdOpRegionProtocolGuid               ## PRODUCES
+gEfiFirmwareVolume2ProtocolGuid        ## CONSUMES
+gGopComponentName2ProtocolGuid         ## CONSUMES
+
+[Guids]
+gEfiEndOfDxeEventGroupGuid
+gSiConfigHobGuid        ## CONSUMES
+gGraphicsDxeConfigGuid
+gMemoryDxeConfigGuid
+gSaDataHobGuid
+gHostBridgeDataHobGuid
+
+[Depex]
+gEfiAcpiTableProtocolGuid AND
+gEfiFirmwareVolume2ProtocolGuid AND
+gSaPolicyProtocolGuid AND
+gEfiPciRootBridgeIoProtocolGuid AND
+gEfiPciHostBridgeResourceAllocationProtocolGuid AND # This is to ensure that 
PCI MMIO resource has been prepared and available for this driver to allocate.
+gEfiHiiDatabaseProtocolGuid
-- 
2.36.1.windows.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#106127): https://edk2.groups.io/g/devel/message/106127
Mute This Topic: https://groups.io/mt/99554481/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-



Reply via email to