[edk2-devel] [PATCH 8/8] AlderlakeSiliconPkg/SystemAgent: Add library and driver modules

Saloni Kasbekar saloni.kasbekar at intel.com
Thu Jun 15 17:53:06 UTC 2023


Adds the following modules:
- Library/DxeSaPolicyLib
- SaInit

Cc: Sai Chaganty <rangasai.v.chaganty at intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone at intel.com>
Cc: Isaac Oram <isaac.w.oram at intel.com>
Cc: Rosen Chuang <rosen.chuang at intel.com>
Signed-off-by: Saloni Kasbekar <saloni.kasbekar at 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/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-




More information about the edk2-devel-archive mailing list