[edk2-devel] [PATCH 34/40] TigerlakeSiliconPkg/SystemAgent: Add Acpi Tables and library instances

Heng Luo heng.luo at intel.com
Mon Feb 1 01:36:51 UTC 2021


REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3171

Adds the following files:
  * SystemAgent/AcpiTables
  * SystemAgent/Library/DxeSaPolicyLib
  * SystemAgent/Library/PeiDxeSmmSaPlatformLib

Cc: Sai Chaganty <rangasai.v.chaganty at intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone at intel.com>
Signed-off-by: Heng Luo <heng.luo at intel.com>
---
 Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/CpuPcieRp.asl                           |  252 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/CpuPcieRpCommon.asl                     |  289 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/PegCommon.asl                           | 1344 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/PegRtd3.asl                             |  124 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Sa.asl                                  |   26 ++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.asl                              |   20 ++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.inf                              |   22 +++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLib.c                   |  264 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLib.inf                 |   48 ++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLibrary.h               |   34 +++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/PeiDxeSmmSaPlatformLib.inf |   32 ++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/SaPlatformLibrary.c        |   68 +++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/SaPlatformLibrary.h        |   21 ++++++++++++++
 13 files changed, 2544 insertions(+)

diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/CpuPcieRp.asl b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/CpuPcieRp.asl
new file mode 100644
index 0000000000..0babf047ed
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/CpuPcieRp.asl
@@ -0,0 +1,252 @@
+/** @file
+  This file contains the CPU PCIe Root Port configuration
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+External(LTRX) // CPU PCIe Root Port 0 Latency Tolerance Reporting Enable
+External(LTRY) // CPU PCIe Root Port 1 Latency Tolerance Reporting Enable
+External(LTRZ) // CPU PCIe Root Port 2 Latency Tolerance Reporting Enable
+External(LTRW) // CPU PCIe Root Port 3 Latency Tolerance Reporting Enable
+External(SMSL) // CPU PCIe Root Port Latency Tolerance Reporting Max Snoop Latency
+External(SNSL) // CPU PCIe Root Port Latency Tolerance Reporting Max No Snoop Latency
+External(PG0E) // CpuPcieRp0Enable <b>0: Disable</b>; 1: Enable
+External(PG1E) // CpuPcieRp1Enable <b>0: Disable</b>; 1: Enable
+External(PG2E) // CpuPcieRp2Enable <b>0: Disable</b>; 1: Enable
+External(PG3E) // CpuPcieRp3Enable <b>0: Disable</b>; 1: Enable
+External(\_SB.PC00.PEG0, DeviceObj)
+External(\_SB.PC00.PEG1, DeviceObj)
+External(\_SB.PC00.PEG2, DeviceObj)
+External(\_SB.PC00.PEG3, DeviceObj)
+External(\_SB.PC00.PEG0.PEGP, DeviceObj)
+External(\_SB.PC00.PEG1.PEGP, DeviceObj)
+External(\_SB.PC00.PEG2.PEGP, DeviceObj)
+External(\_SB.PC00.PEG3.PEGP, DeviceObj)
+External(\AR02)
+External(\PD02)
+External(\AR0A)
+External(\PD0A)
+External(\AR0B)
+External(\PD0B)
+External(\AR0C)
+External(\PD0C)
+External(VMDE)
+External(VMCP)
+External(MPGN)
+External(PBR1)
+External(PBR2)
+External(PBR3)
+
+Scope (\_SB.PC00.PEG0) {
+
+  Name(SLOT, 0) // CPU PCIe root port index 0 corresponds to PEG60 (0/6/0)
+
+  Method (_STA, 0x0, NotSerialized) {
+    if(PG0E == 1) { // If CPU PCIe RP0 enabled?
+      Return(0x0F)
+    }
+    Return(0x00)
+  }
+
+  Name(LTEN, 0)
+  Name(LMSL, 0)
+  Name(LNSL, 0)
+
+  Method(_INI)
+  {
+    Store (LTRX, LTEN)
+    Store (SMSL, LMSL)
+    Store (SNSL, LNSL)
+    If(LAnd(CondRefOf(VMCP),CondRefOf(VMDE))) {
+      If(LAnd(LEqual(VMDE,1),LNotEqual(And(VMCP,0x8),0))) {
+        Store (1, CPMV)
+      }
+    }
+  }
+
+  Method(_PRT,0) {
+    If(PICM) {
+      Return(AR02)
+    } // APIC mode
+    Return (PD02) // PIC Mode
+  } // end _PRT
+
+  Include("CpuPcieRpCommon.asl")
+} // PEG0 scope end
+
+Scope (\_SB.PC00.PEG1) {
+
+  Name(SLOT, 1) // CPU PCIe root port index 1 corresponds to PEG10 (0/1/0)
+
+  Method (_STA, 0x0, NotSerialized) {
+    if(PG1E == 1) { // If CPU PCIe RP1 enabled?
+      Return(0x0F)
+    }
+    Return(0x00)
+  }
+
+  Name(LTEN, 0)
+  Name(LMSL, 0)
+  Name(LNSL, 0)
+
+  Method(_INI)
+  {
+    Store (LTRY, LTEN)
+    Store (SMSL, LMSL)
+    Store (SNSL, LNSL)
+    If(LAnd(CondRefOf(VMCP),CondRefOf(VMDE))) {
+      If(LAnd(LEqual(VMDE,1),LNotEqual(And(VMCP,0x1),0))) {
+        Store (1, CPMV)
+      }
+    }
+  }
+
+  Method(_PRT,0) {
+    If(PICM) {
+      Return(AR0A)
+    } // APIC mode
+    Return (PD0A) // PIC Mode
+  } // end _PRT
+
+  Include("CpuPcieRpCommon.asl")
+} // PEG1 scope end
+
+Scope (\_SB.PC00.PEG2) {
+
+  Name(SLOT, 2) // CPU PCIe root port index 2 corresponds to PEG11 (0/1/1)
+
+  Method (_STA, 0x0, NotSerialized) {
+    if(PG2E == 1) { // If CPU PCIe RP2 enabled?
+      Return(0x0F)
+    }
+    Return(0x00)
+  }
+
+  Name(LTEN, 0)
+  Name(LMSL, 0)
+  Name(LNSL, 0)
+
+  Method(_INI)
+  {
+    Store (LTRZ, LTEN)
+    Store (SMSL, LMSL)
+    Store (SNSL, LNSL)
+    If(LAnd(CondRefOf(VMCP),CondRefOf(VMDE))) {
+      If(LAnd(LEqual(VMDE,1),LNotEqual(And(VMCP,0x2),0))) {
+        Store (1, CPMV)
+      }
+    }
+  }
+
+  Method(_PRT,0) {
+    If(PICM) {
+      Return(AR0B)
+    } // APIC mode
+    Return (PD0B) // PIC Mode
+  } // end _PRT
+
+  Include("CpuPcieRpCommon.asl")
+} // PEG2 scope end
+
+If (CondRefOf(\_SB.PC00.PEG3)) {
+  Scope (\_SB.PC00.PEG3) {
+
+    Name(SLOT, 3) // CPU PCIe root port index 3 corresponds to PEG12 (0/1/2)
+
+    Method (_STA, 0x0, NotSerialized) {
+      if(PG3E == 1) { // If CPU PCIe RP3 enabled?
+        Return(0x0F)
+      }
+      Return(0x00)
+    }
+
+    Name(LTEN, 0)
+    Name(LMSL, 0)
+    Name(LNSL, 0)
+
+    Method(_INI)
+    {
+      Store (LTRW, LTEN)
+      Store (SMSL, LMSL)
+      Store (SNSL, LNSL)
+      If(LAnd(CondRefOf(VMCP),CondRefOf(VMDE))) {
+        If(LAnd(LEqual(VMDE,1),LNotEqual(And(VMCP,0x4),0))) {
+          Store (1, CPMV)
+        }
+      }
+    }
+
+    Method(_PRT,0) {
+      If(PICM) {
+        Return(AR0C)
+      } // APIC mode
+      Return (PD0C) // PIC Mode
+    } // end _PRT
+
+    Include("CpuPcieRpCommon.asl")
+  } // PEG3 scope end
+}
+
+Scope(\_SB.PC00.PEG0.PEGP) {
+  Method(_PRW, 0) {
+    Return(GPRW(0x69, 4)) // can wakeup from S4 state
+  }
+}
+
+
+If (PBR1) {
+  Scope(\_SB.PC00.PEG1.PEGP) {
+    Method(_S0W, 0) { Return(4)} //D3cold is supported
+
+    Device (PEGD) {
+      Method(_S0W, 0) { Return(4)} //D3cold is supported
+      Name(_ADR, 0x00000000)
+      Method(_PRW, 0) { Return(GPRW(0x69, 4)) } // can wakeup from S4 state
+    }
+  } // end "P.E.G. Port Slot x16"
+}
+
+Scope(\_SB.PC00.PEG1.PEGP) {
+  Method(_PRW, 0) {
+    Return(GPRW(0x69, 4)) // can wakeup from S4 state
+  }
+}
+
+
+If (PBR2) {
+  Scope(\_SB.PC00.PEG2.PEGP) {
+    Method(_S0W, 0) { Return(4)} //D3cold is supported
+
+    Device (PEGD) {
+      Method(_S0W, 0) { Return(4)} //D3cold is supported
+      Name(_ADR, 0x00000000)
+      Method(_PRW, 0) { Return(GPRW(0x69, 4)) } // can wakeup from S4 state
+    }
+  } // end "P.E.G. Port Slot 2x8"
+}
+
+Scope(\_SB.PC00.PEG2.PEGP) {
+  Method(_PRW, 0) {
+    Return(GPRW(0x69, 4)) // can wakeup from S4 state
+  }
+}
+
+If (PBR3) {
+  Scope(\_SB.PC00.PEG3.PEGP) {
+    Method(_S0W, 0) { Return(4)} //D3cold is supported
+
+    Device (PEGD) {
+      Method(_S0W, 0) { Return(4)} //D3cold is supported
+      Name(_ADR, 0x00000000)
+      Method(_PRW, 0) { Return(GPRW(0x69, 4)) } // can wakeup from S4 state
+    }
+  } // end "P.E.G. Port Slot 1x8 - 2x4"
+}
+
+If (CondRefOf(\_SB.PC00.PEG3)) {
+  Scope(\_SB.PC00.PEG3.PEGP) {
+    Method(_PRW, 0) {
+      Return(GPRW(0x69, 4)) // can wakeup from S4 state
+    }
+  }
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/CpuPcieRpCommon.asl b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/CpuPcieRpCommon.asl
new file mode 100644
index 0000000000..81f785dfc5
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/CpuPcieRpCommon.asl
@@ -0,0 +1,289 @@
+/** @file
+  This file contains the CPU PCIe Root Port configuration
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+  External(ECR1)
+  External(GPRW, MethodObj)
+  External(PICM)
+  External(\_SB.PC00.PC2M, MethodObj)
+  External(_ADR, IntObj)
+
+
+  OperationRegion(PXCS,SystemMemory,\_SB.PC00.PC2M(_ADR),0x480)
+  Field(PXCS, AnyAcc, NoLock, Preserve)
+  {
+    Offset(0),
+    VDID, 32,
+    Offset(0x50), // LCTL - Link Control Register
+    L0SE, 1,      // 0, L0s Entry Enabled
+    , 3,
+    LDIS, 1,
+    , 3,
+    Offset(0x52), // LSTS - Link Status Register
+    , 13,
+    LASX, 1,      // 0, Link Active Status
+    Offset(0x5A), // SLSTS[7:0] - Slot Status Register
+    ABPX, 1,      // 0, Attention Button Pressed
+    , 2,
+    PDCX, 1,      // 3, Presence Detect Changed
+    , 2,
+    PDSX, 1,      // 6, Presence Detect State
+    , 1,
+    Offset(0x60), // RSTS - Root Status Register
+    , 16,
+    PSPX, 1,      // 16,  PME Status
+    Offset(0xA4),
+    D3HT, 2,      // Power State
+    Offset(0xD8), // 0xD8, MPC - Miscellaneous Port Configuration Register
+    , 30,
+    HPEX, 1,      // 30,  Hot Plug SCI Enable
+    PMEX, 1,      // 31,  Power Management SCI Enable
+    Offset(0xE0), // 0xE0, SPR - Scratch Pad Register
+    , 0,
+    SCB0, 1,      // Sticky Scratch Pad Bit SCB0
+    Offset(0xE2), // 0xE2, RPPGEN - Root Port Power Gating Enable
+    , 2,
+    L23E, 1,       // 2,   L23_Rdy Entry Request (L23ER)
+    L23R, 1,       // 3,   L23_Rdy to Detect Transition (L23R2DT)
+    Offset(0x324), // 0x324 - PCIEDBG
+    , 3,
+    LEDM, 1,       // PCIEDBG.DMIL1EDM
+    Offset(0x328), // 0x328 - PCIESTS1
+    , 24,
+    LTSM, 8,
+  }
+  Field(PXCS,AnyAcc, NoLock, WriteAsZeros)
+  {
+    Offset(0xDC), // 0xDC, SMSCS - SMI/SCI Status Register
+    , 30,
+    HPSX, 1,      // 30,  Hot Plug SCI Status
+    PMSX, 1       // 31,  Power Management SCI Status
+  }
+
+  //
+  // L23D method recovers link from L2 or L3 state. Used for RTD3 flows, right after endpoint is powered up and exits reset.
+  // This flow is implemented in ASL because rootport registers used for L2/L3 entry/exit
+  // are proprietary and OS drivers don't know about them.
+  //
+  Method (L23D, 0, Serialized) {
+    If(LNotEqual(SCB0,0x1)) {
+      Return()
+    }
+
+    /// Set L23_Rdy to Detect Transition  (L23R2DT)
+    Store(1, L23R)
+    Store(0, Local0)
+    /// Wait for transition to Detect
+    While(L23R) {
+      If(Lgreater(Local0, 4))
+      {
+        Break
+      }
+      Sleep(16)
+      Increment(Local0)
+    }
+    Store(0,SCB0)
+
+    /// Once in Detect, wait up to 124 ms for Link Active (typically happens in under 70ms)
+    /// Worst case per PCIe spec from Detect to Link Active is:
+    /// 24ms in Detect (12+12), 72ms in Polling (24+48), 28ms in Config (24+2+2+2+2)
+    Store(0, Local0)
+    While(LEqual(LASX,0)) {
+      If(Lgreater(Local0, 8))
+      {
+        Break
+      }
+      Sleep(16)
+      Increment(Local0)
+    }
+  }
+
+  //
+  // DL23 method puts link to L2 or L3 state. Used for RTD3 flows, before endpoint is powered down.
+  // This flow is implemented in ASL because rootport registers used for L2/L3 entry/exit
+  // are proprietary and OS drivers don't know about them.
+  //
+  Method (DL23, 0, Serialized) {
+    Store(1, L23E)
+    Sleep(16)
+    Store(0, Local0)
+    While(L23E) {
+      If(Lgreater(Local0, 4))
+      {
+        Break
+      }
+      Sleep(16)
+      Increment(Local0)
+    }
+    Store(1,SCB0)
+  }
+
+  Name(LTRV, Package(){0,0,0,0})
+  Name(CPMV, 0) // CPU Rp Mapped under VMD
+
+  //
+  // _DSM Device Specific Method
+  //
+  // Arg0: UUID Unique function identifier
+  // Arg1: Integer Revision Level
+  // Arg2: Integer Function Index (0 = Return Supported Functions)
+  // Arg3: Package Parameters
+  Method(_DSM, 4, Serialized) {
+    //
+    // Switch based on which unique function identifier was passed in
+    //
+    If (LEqual(Arg0, ToUUID ("E5C937D0-3553-4d7a-9117-EA4D19C3434D"))) {
+      //
+      // _DSM Definitions for Latency Tolerance Reporting
+      //
+      // Arguments:
+      // Arg0: UUID: E5C937D0-3553-4d7a-9117-EA4D19C3434D
+      // Arg1: Revision ID: 3
+      // Arg2: Function Index: 0, 6, 8, 9
+      // Arg3: Empty Package
+      //
+      // Switch by function index
+      //
+      Switch(ToInteger(Arg2)) {
+        //
+        // Function Index:0
+        // Standard query - A bitmask of functions supported
+        //
+        Case (0) {
+          Name(OPTS,Buffer(2){0,0})
+          CreateBitField(OPTS,0,FUN0)
+          CreateBitField(OPTS,6,FUN6)
+          CreateBitField(OPTS,8,FUN8)
+          CreateBitField(OPTS,9,FUN9)
+
+          Store(1,FUN0)
+          if(LEqual(LTEN,1)) {
+            Store(1,Fun6)
+          }
+
+          If (LGreaterEqual(Arg1, 2)){ // test Arg1 for Revision ID: 2
+            If(CondRefOf(ECR1)) {
+              if(LEqual(ECR1,1)){
+                if (LGreaterEqual(Arg1, 3)){ // test Arg1 for Revision ID: 3
+                  Store(1,Fun8)
+                  Store(1,Fun9)
+                }
+              }
+            }
+          }
+          Return (OPTS)
+        }
+
+        //
+        // Function Index: 6
+        // LTR Extended Capability Structure
+        //
+        Case(6) {
+          if (LGreaterEqual(Arg1, 2)){ // test Arg1 for Revision ID: 2
+            Store(And(ShiftRight(LMSL,10),7), Index(LTRV, 0))
+            Store(And(LMSL,0x3FF), Index(LTRV, 1))
+            Store(And(ShiftRight(LNSL,10),7), Index(LTRV, 2))
+            Store(And(LNSL,0x3FF), Index(LTRV, 3))
+            Return (LTRV)
+          }
+        }
+        Case(8) { //ECR ACPI additions for FW latency optimizations, DSM for Avoiding Power-On Reset Delay Duplication on Sx Resume
+          If(CondRefOf(ECR1)) {
+            if(LEqual(ECR1,1)){
+              if (LGreaterEqual(Arg1, 3)) { // test Arg1 for Revision ID: 3
+                return (1)
+              }
+            }
+          }
+        }
+        Case(9) { //ECR ACPI additions for FW latency optimizations, DSM for Specifying Device Readiness Durations
+          If(CondRefOf(ECR1)) {
+            if(LEqual(ECR1,1)){
+              if (LGreaterEqual(Arg1, 3)) { // test Arg1 for Revision ID: 3
+                return(Package(5){50000,Ones,Ones,50000,Ones})
+              }
+            }
+          }
+        }
+      } // End of switch(Arg2)
+    } // End of if
+    return (Buffer() {0x00})
+  } // End of _DSM
+
+  Method(_PRW, 0) {
+    Return(GPRW(0x69, 4)) // can wakeup from S4 state
+  }
+
+  Method(_PS0,0,Serialized)
+  {
+    If (LEqual(HPEX, 1)) {
+      Store(0, HPEX) // Disable Hot Plug SCI
+      Store(1, HPSX) // Clear Hot Plug SCI status
+    }
+    If (LEqual (PMEX, 1)) {
+      Store(0, PMEX) // Disable Power Management SCI
+      Store(1, PMSX) // Clear Power Management SCI status
+    }
+  }
+  Method(_PS3,0,Serialized)
+  {
+    If (LEqual (HPEX, 0)) {
+      Store(1, HPEX) // Enable Hot Plug SCI
+      Store(1, HPSX) // Clear Hot Plug SCI status
+    }
+    If (LEqual(PMEX, 0)) {
+      Store(1, PMEX) // Enable Power Management SCI
+      Store(1, PMSX) // Clear Power Management SCI status
+    }
+  }
+
+  Method (_DSD, 0) {
+    Return (
+      Package () {
+        ToUUID("FDF06FAD-F744-4451-BB64-ECD792215B10"),
+        Package () {
+          Package (2) {"FundamentalDeviceResetTriggeredOnD3ToD0", 1},
+        }
+      }
+    ) // End of Return ()
+  }
+
+  //
+  // PCI_EXP_STS Handler for PCIE Root Port
+  //
+  Method(HPME,0,Serialized) {
+    If(LAnd(LNotEqual(VDID,0xFFFFFFFF), LEqual(PMSX,1))) { //if port exists and has PME SCI Status set...
+      Store(1,PMSX) // clear rootport's PME SCI status
+      Store(1,PSPX) // consume one pending PME status to prevent it from blocking the queue
+      Return(0x01)
+    }
+    Return(0x00)
+  }
+
+  //
+  // Sub-Method of _L61 Hot-Plug event
+  // _L61 event handler should invoke this method to support HotPlug wake event from PEG RP
+  //
+  Method(HPEV,0,Serialized) {
+    If(LAnd(LNotEqual(VDID,0xFFFFFFFF), HPSX)) {
+      // Clear HotPlug SCI event status
+      Store(1, HPSX)
+
+      If(LEqual(PDCX, 1)) {
+        // Clear Presence Detect Changed
+        Store(1,PDCX)
+
+        If(LEqual(PDSX, 0)) {
+          // The PCI Express slot is empty, so disable L0s on hot unplug
+          //
+          Store(0,L0SE)
+        }
+        // Perform proper notification
+        // to the OS.
+        Notify(^,0)
+      }
+    }
+  }
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/PegCommon.asl b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/PegCommon.asl
new file mode 100644
index 0000000000..68b10309d4
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/PegCommon.asl
@@ -0,0 +1,1344 @@
+/** @file
+  This file contains the device definitions of the SystemAgent
+  PCIE ACPI Reference Code.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+External(\_SB.ISME, MethodObj)
+External(\_SB.SHPO, MethodObj)
+External(\_SB.CAGS, MethodObj)
+External(\_SB.GGOV, MethodObj)
+External(\_SB.SGOV, MethodObj)
+External(\_SB.PC00.PEG0, DeviceObj)
+External(\_SB.PC00.PEG1, DeviceObj)
+External(\_SB.PC00.PEG2, DeviceObj)
+External(\_SB.PC00.PEG3, DeviceObj)
+External(\_SB.PC00.PEG0.PPRW, MethodObj)
+External(\_SB.PC00.PEG1.PPRW, MethodObj)
+External(\_SB.PC00.PEG2.PPRW, MethodObj)
+External(\_SB.PC00.PEG3.PPRW, MethodObj)
+External(\_SB.PC00.PC2M, MethodObj)
+External(P8XH, MethodObj)
+External(SPCO, MethodObj)
+External(PINI, MethodObj) // Platform specific PCIe root port initialization
+External(PRES, MethodObj)
+External(GPRW, MethodObj)
+External(\SLOT)
+External(\P0WK)
+External(\P1WK)
+External(\P2WK)
+External(\P3WK)
+External(\XBAS)
+External(\SBN0)
+External(\SBN1)
+External(\SBN2)
+External(\SBN3)
+External(\EECP)
+External(\EEC1)
+External(\EEC2)
+External(\EEC3)
+External(\SGGP)
+External(\HRE0)
+External(\HRG0)
+External(\HRA0)
+External(\PWE0)
+External(\PWG0)
+External(\PWA0)
+External(\P1GP)
+External(\HRE1)
+External(\HRG1)
+External(\HRA1)
+External(\PWE1)
+External(\PWG1)
+External(\PWA1)
+External(\P2GP)
+External(\HRE2)
+External(\HRG2)
+External(\HRA2)
+External(\PWE2)
+External(\PWG2)
+External(\PWA2)
+External(\P3GP)
+External(\HRE3)
+External(\HRG3)
+External(\HRA3)
+External(\PWE3)
+External(\PWG3)
+External(\PWA3)
+External(\P0SC)
+External(\P1SC)
+External(\P2SC)
+External(\P3SC)
+External(\DLPW)
+External(\DLHR)
+External(\OBFX)
+External(\OBFY)
+External(\OBFZ)
+External(\OBFA)
+External(\OSYS)
+
+//GPE Event handling - Start
+Scope(\_GPE) {
+  //
+  // _L6F Method call for PEG0/1/2/3 ports to handle 2-tier RTD3 GPE events
+  //
+  Method(P0L6,0)
+  {
+    // PEG0 Device Wake Event
+    If (\_SB.ISME(P0WK))
+    {
+      \_SB.SHPO(P0WK, 1)             // set gpio ownership to driver(0=ACPI mode, 1=GPIO mode)
+      Notify(\_SB.PC00.PEG0, 0x02)   // device wake
+      \_SB.CAGS(P0WK)                // Clear GPE status bit for PEG0 WAKE
+    }
+  }
+
+  Method(P1L6,0)
+  {
+    // PEG1 Device Wake Event
+    If (\_SB.ISME(P1WK))
+    {
+      \_SB.SHPO(P1WK, 1)             // set gpio ownership to driver(0=ACPI mode, 1=GPIO mode)
+      Notify(\_SB.PC00.PEG1, 0x02)   // device wake
+      \_SB.CAGS(P1WK)                // Clear GPE status bit for PEG1 WAKE
+    }
+  }
+
+  Method(P2L6,0)
+  {
+    // PEG2 Device Wake Event
+    If (\_SB.ISME(P2WK))
+    {
+      \_SB.SHPO(P2WK, 1)             // set gpio ownership to driver(0=ACPI mode, 1=GPIO mode)
+      Notify(\_SB.PC00.PEG2, 0x02)   // device wake
+      \_SB.CAGS(P2WK)                // Clear GPE status bit for PEG2 WAKE
+    }
+  }
+
+  If (CondRefOf(\_SB.PC00.PEG3)) {
+    Method(P3L6,0)
+    {
+      // PEG2 Device Wake Event
+      If (\_SB.ISME(P3WK))
+      {
+        \_SB.SHPO(P3WK, 1)             // set gpio ownership to driver(0=ACPI mode, 1=GPIO mode)
+        Notify(\_SB.PC00.PEG3, 0x02)   // device wake
+        \_SB.CAGS(P3WK)                // Clear GPE status bit for PEG2 WAKE
+      }
+    }
+  }
+} //Scope(\_GPE)
+
+If(LAnd((LEqual(HGMD,2)), (LEqual(HGST,1)))) {
+///
+/// P.E.G. Root Port D6F0
+///
+Scope(\_SB.PC00.PEG0) {
+  Name(WKEN, 0)
+
+  PowerResource(PG00, 0, 0) {
+    Name(_STA, One)
+    Method(_ON, 0, Serialized) {
+      If(LGreater(OSYS,2009)) {
+        PGON(0)
+        Store(One, _STA)
+      }
+    }
+    Method(_OFF, 0, Serialized) {
+      If(LGreater(OSYS,2009)) {
+        PGOF(0)
+        Store(Zero, _STA)
+      }
+    }
+  } //End of PowerResource(PG00, 0, 0)
+
+  Name(_PR0,Package(){PG00})
+  Name(_PR3,Package(){PG00})
+
+  ///
+  /// This method is used to enable/disable wake from PEG60 (WKEN)
+  ///
+  Method(_DSW, 3)
+  {
+    If(Arg1)
+    {
+      Store(0, WKEN)        /// If entering Sx, need to disable WAKE# from generating runtime PME
+    }
+    Else
+    { /// If Staying in S0
+      If(LAnd(Arg0, Arg2))  ///- Check if Exiting D0 and arming for wake
+      {
+        Store(1, WKEN)      ///- Set PME
+      } Else {
+        Store(0, WKEN)    ///- Disable runtime PME, either because staying in D0 or disabling wake
+      }
+    }
+  } // End _DSW
+
+  ///
+  /// This method is used to change the GPIO ownership back to ACPI and will be called in PEG OFF Method
+  ///
+  Method(P0EW, 0)
+  {
+    If(WKEN)
+    {
+      If(LNotEqual(SGGP, 0x0))
+      {
+        If(LEqual(SGGP, 0x1))      // GPIO mode
+        {
+          \_SB.SGOV(P0WK, 0x1)
+          \_SB.SHPO(P0WK, 0x0)     // set gpio ownership to ACPI(0=ACPI mode, 1=GPIO mode)
+        }
+      }
+    }
+  } // End P0EW
+
+  Method(_S0W, 0) {
+    Return(4) //D3cold is supported
+  }
+}// end "P.E.G. Root Port D6F0"
+
+///
+/// P.E.G. Root Port D1F0
+///
+Scope(\_SB.PC00.PEG1) {
+  Name(WKEN, 0)
+
+  PowerResource(PG01, 0, 0) {
+    Name(_STA, One)
+    Method(_ON, 0, Serialized) {
+      If(LGreater(OSYS,2009)) {
+        PGON(1)
+        Store(One, _STA)
+      }
+    }
+    Method(_OFF, 0, Serialized) {
+      If(LGreater(OSYS,2009)) {
+        PGOF(1)
+        Store(Zero, _STA)
+      }
+    }
+  } //End of PowerResource(PG01, 0, 0)
+
+  Name(_PR0,Package(){PG01})
+  Name(_PR3,Package(){PG01})
+
+  ///
+  /// This method is used to enable/disable wake from PEG10 (WKEN)
+  ///
+  Method(_DSW, 3)
+  {
+    If(Arg1)
+    {
+      Store(0, WKEN)        /// If entering Sx, need to disable WAKE# from generating runtime PME
+    }
+    Else
+    { /// If Staying in S0
+      If(LAnd(Arg0, Arg2))  ///- Check if Exiting D0 and arming for wake
+      {
+        Store(1, WKEN)      ///- Set PME
+      } Else {
+        Store(0, WKEN)    ///- Disable runtime PME, either because staying in D0 or disabling wake
+      }
+    }
+  } // End _DSW
+
+  ///
+  /// This method is used to change the GPIO ownership back to ACPI and will be called in PEG OFF Method
+  ///
+  Method(P1EW, 0)
+  {
+    If(WKEN)
+    {
+      If(LNotEqual(P1GP, 0x0))
+      {
+        If(LEqual(P1GP, 0x1))      // GPIO mode
+        {
+          \_SB.SGOV(P1WK, 0x1)
+          \_SB.SHPO(P1WK, 0x0)     // set gpio ownership to ACPI(0=ACPI mode, 1=GPIO mode)
+        }
+      }
+    }
+  } // End P1EW
+}// end "P.E.G. Root Port D1F0"
+
+///
+/// P.E.G. Root Port D1F1
+///
+Scope(\_SB.PC00.PEG2) {
+  Name(WKEN, 0)
+
+  PowerResource(PG02, 0, 0) {
+    Name(_STA, One)
+    Method(_ON, 0, Serialized) {
+      If(LGreater(OSYS,2009)) {
+        PGON(2)
+        Store(One, _STA)
+      }
+    }
+    Method(_OFF, 0, Serialized) {
+      If(LGreater(OSYS,2009)) {
+        PGOF(2)
+        Store(Zero, _STA)
+      }
+    }
+  } //End of PowerResource(PG02, 0, 0)
+
+  Name(_PR0,Package(){PG02})
+
+  Name(_PR3,Package(){PG02})
+
+  ///
+  /// This method is used to enable/disable wake from PEG11 (WKEN)
+  ///
+  Method(_DSW, 3)
+  {
+    If(Arg1)
+    {
+      Store(0, WKEN)        /// If entering Sx, need to disable WAKE# from generating runtime PME
+    }
+    Else
+    { /// If Staying in S0
+      If(LAnd(Arg0, Arg2))  ///- Check if Exiting D0 and arming for wake
+      {
+        Store(1, WKEN)      ///- Set PME
+      } Else {
+        Store(0, WKEN)    ///- Disable runtime PME, either because staying in D0 or disabling wake
+      }
+    }
+  } // End _DSW
+
+  ///
+  /// This method is used to change the GPIO ownership back to ACPI and will be called in PEG OFF Method
+  ///
+  Method(P2EW, 0)
+  {
+    If(WKEN)
+    {
+      If(LNotEqual(P2GP, 0x0))
+      {
+        If(LEqual(P2GP, 0x1))      // GPIO mode
+        {
+          \_SB.SGOV(P2WK, 0x1)
+          \_SB.SHPO(P2WK, 0x0)     // set gpio ownership to ACPI(0=ACPI mode, 1=GPIO mode)
+        }
+      }
+    }
+  } // End P2EW
+}// end "P.E.G. Root Port D1F1"
+
+///
+/// P.E.G. Root Port D1F2
+///
+Scope(\_SB.PC00.PEG3) {
+  Name(WKEN, 0)
+
+  PowerResource(PG03, 0, 0) {
+    Name(_STA, One)
+    Method(_ON, 0, Serialized) {
+      If(LGreater(OSYS,2009)) {
+        PGON(3)
+        Store(One, _STA)
+      }
+    }
+    Method(_OFF, 0, Serialized) {
+      If(LGreater(OSYS,2009)) {
+        PGOF(3)
+        Store(Zero, _STA)
+      }
+    }
+  } //End of PowerResource(PG03, 0, 0)
+
+  Name(_PR0,Package(){PG03})
+  Name(_PR3,Package(){PG03})
+
+  ///
+  /// This method is used to enable/disable wake from PEG12 (WKEN)
+  ///
+  Method(_DSW, 3)
+  {
+    If(Arg1)
+    {
+      Store(0, WKEN)        /// If entering Sx, need to disable WAKE# from generating runtime PME
+    }
+    Else
+    { /// If Staying in S0
+      If(LAnd(Arg0, Arg2))  ///- Check if Exiting D0 and arming for wake
+      {
+        Store(1, WKEN)      ///- Set PME
+      } Else {
+        Store(0, WKEN)    ///- Disable runtime PME, either because staying in D0 or disabling wake
+      }
+    }
+  } // End _DSW
+
+  ///
+  /// This method is used to change the GPIO ownership back to ACPI and will be called in PEG OFF Method
+  ///
+  Method(P3EW, 0)
+  {
+    If(WKEN)
+    {
+      If(LNotEqual(P3GP, 0x0))
+      {
+        If(LEqual(P3GP, 0x1))      // GPIO mode
+        {
+          \_SB.SGOV(P3WK, 0x1)
+          \_SB.SHPO(P3WK, 0x0)     // set gpio ownership to ACPI(0=ACPI mode, 1=GPIO mode)
+        }
+      }
+    }
+  } // End P3EW
+}// end "P.E.G. Root Port D1F2"
+
+Scope (\_SB.PC00) {
+
+    Name(IVID, 0xFFFF) //Invalid Vendor ID
+
+    Name(PEBA, 0) //PCIE base address
+
+    Name(PION, 0) //PEG index for ON Method
+    Name(PIOF, 0) //PEG index for OFF Method
+
+    Name(PBUS, 0) //PEG Rootport bus no
+    Name(PDEV, 0) //PEG Rootport device no
+    Name(PFUN, 0) //PEG Rootport function no
+
+    Name(EBUS, 0) //Endpoint bus no
+    Name(EDEV, 0) //Endpoint device no
+    Name(EFN0, 0) //Endpoint function no 0
+    Name(EFN1, 1) //Endpoint function no 1
+
+    Name(LTRS, 0)
+    Name(OBFS, 0)
+
+    Name(DSOF, 0x06) //Device status PCI offset
+    Name(CPOF, 0x34) //Capabilities pointer PCI offset
+    Name(SBOF, 0x19) //PCI-2-PCI Secondary Bus number
+
+    // PEG0 Endpoint variable to save/restore Link Capability, Link control, Subsytem VendorId and Device Id
+    Name (ELC0, 0x00000000)
+    Name (ECP0, 0xffffffff)
+    Name (H0VI, 0x0000)
+    Name (H0DI, 0x0000)
+
+    // PEG1 Endpoint variable to save/restore Link Capability, Link control, Subsytem VendorId and Device Id
+    Name (ELC1, 0x00000000)
+    Name (ECP1, 0xffffffff)
+    Name (H1VI, 0x0000)
+    Name (H1DI, 0x0000)
+
+    // PEG2 Endpoint variable to save/restore Link Capability, Link control, Subsytem VendorId and Device Id
+    Name (ELC2, 0x00000000)
+    Name (ECP2, 0xffffffff)
+    Name (H2VI, 0x0000)
+    Name (H2DI, 0x0000)
+
+    // PEG3 Endpoint variable to save/restore Link Capability, Link control, Subsytem VendorId and Device Id
+    Name (ELC3, 0x00000000)
+    Name (ECP3, 0xffffffff)
+    Name (H3VI, 0x0000)
+    Name (H3DI, 0x0000)
+
+    // PEG_AFELN[15:0]VMTX2_OFFSET variables
+    Name(AFL0, 0)
+    Name(AFL1, 0)
+    Name(AFL2, 0)
+    Name(AFL3, 0)
+    Name(AFL4, 0)
+    Name(AFL5, 0)
+    Name(AFL6, 0)
+    Name(AFL7, 0)
+    Name(AFL8, 0)
+    Name(AFL9, 0)
+    Name(AFLA, 0)
+    Name(AFLB, 0)
+    Name(AFLC, 0)
+    Name(AFLD, 0)
+    Name(AFLE, 0)
+    Name(AFLF, 0)
+
+    //
+    // Define a Memory Region for PEG60 root port that will allow access to its
+    // Register Block.
+    //
+    OperationRegion(OPG0, SystemMemory, Add(XBAS,0x30000), 0x1000)
+    Field(OPG0, AnyAcc,NoLock,Preserve)
+    {
+      Offset(0),
+      P0VI,   16,        //Vendor ID PCI offset
+      P0DI,   16,        //Device ID PCI offset
+      Offset(0x06),
+      DSO0,   16,        //Device status PCI offset
+      Offset(0x34),
+      CPO0,   8,         //Capabilities pointer PCI offset
+      Offset(0x0B0),
+      ,       4,
+      P0LD,   1,         //Link Disable
+      Offset(0x11A),
+      ,       1,
+      P0VC,   1,         //VC0RSTS.VC0NP
+      Offset(0x214),
+      ,       16,
+      P0LS,   4,         //PEGSTS.LKS
+      Offset(0x248),
+      ,       7,
+      Q0L2,   1,         //L23_Rdy Entry Request for RTD3
+      Q0L0,   1,         //L23 to Detect Transition for RTD3
+      Offset(0x504),
+      HST0,  32,
+      Offset(0x508),
+      P0TR,   1,         //TRNEN.TREN
+      Offset(0xC74),
+      P0LT,   4,         //LTSSM_FSM_RESTORE.LTSSM_FSM_PS
+      Offset(0xD0C),
+      LRV0,  32,
+    }
+
+    //
+    // Define a Memory Region for Endpoint on PEG60 root port
+    //
+    OperationRegion (PCS0, SystemMemory, Add(XBAS,ShiftLeft(SBN0,20)), 0xF0)
+    Field(PCS0, DWordAcc, Lock, Preserve)
+    {
+        Offset(0x0),
+        D0VI, 16,
+        Offset(0x2C),
+        S0VI, 16,
+        S0DI, 16,
+    }
+
+    OperationRegion(CAP0, SystemMemory, Add(Add(XBAS,ShiftLeft(SBN0,20)),EECP),0x14)
+    Field(CAP0,DWordAcc, NoLock,Preserve)
+    {
+        Offset(0x0C),                    // Link Capabilities Register
+        LCP0,   32,                      // Link Capabilities Register Data
+        Offset(0x10),
+        LCT0,   16,                      // Link Control register
+    }
+
+    //
+    // Define a Memory Region for PEG10 root port that will allow access to its
+    // Register Block.
+    //
+    OperationRegion(OPG1, SystemMemory, Add(XBAS,0x8000), 0x1000)
+    Field(OPG1, AnyAcc,NoLock,Preserve)
+    {
+      Offset(0),
+      P1VI,   16,        //Vendor ID PCI offset
+      P1DI,   16,        //Device ID PCI offset
+      Offset(0x06),
+      DSO1,   16,        //Device status PCI offset
+      Offset(0x34),
+      CPO1,   8,         //Capabilities pointer PCI offset
+      Offset(0x0B0),
+      ,       4,
+      P1LD,   1,         //Link Disable
+      Offset(0x11A),
+      ,       1,
+      P1VC,   1,         //VC0RSTS.VC0NP
+      Offset(0x214),
+      ,       16,
+      P1LS,   4,         //PEGSTS.LKS
+      Offset(0x248),
+      ,       7,
+      Q1L2,   1,         //L23_Rdy Entry Request for RTD3
+      Q1L0,   1,         //L23 to Detect Transition for RTD3
+      Offset(0x504),
+      HST1,  32,
+      Offset(0x508),
+      P1TR,   1,         //TRNEN.TREN
+      Offset(0x70C),
+      PA0V,  32,         //PEG_AFELN0VMTX2_OFFSET
+      Offset(0x71C),
+      PA1V,  32,         //PEG_AFELN1VMTX2_OFFSET
+      Offset(0x72C),
+      PA2V,  32,         //PEG_AFELN2VMTX2_OFFSET
+      Offset(0x73C),
+      PA3V,  32,         //PEG_AFELN3VMTX2_OFFSET
+      Offset(0x74C),
+      PA4V,  32,         //PEG_AFELN4VMTX2_OFFSET
+      Offset(0x75C),
+      PA5V,  32,         //PEG_AFELN5VMTX2_OFFSET
+      Offset(0x76C),
+      PA6V,  32,         //PEG_AFELN6VMTX2_OFFSET
+      Offset(0x77C),
+      PA7V,  32,         //PEG_AFELN7VMTX2_OFFSET
+      Offset(0x78C),
+      PA8V,  32,         //PEG_AFELN8VMTX2_OFFSET
+      Offset(0x79C),
+      PA9V,  32,         //PEG_AFELN9VMTX2_OFFSET
+      Offset(0x7AC),
+      PAAV,  32,         //PEG_AFELNAVMTX2_OFFSET
+      Offset(0x7BC),
+      PABV,  32,         //PEG_AFELNBVMTX2_OFFSET
+      Offset(0x7CC),
+      PACV,  32,         //PEG_AFELNCVMTX2_OFFSET
+      Offset(0x7DC),
+      PADV,  32,         //PEG_AFELNDVMTX2_OFFSET
+      Offset(0x7EC),
+      PAEV,  32,         //PEG_AFELNEVMTX2_OFFSET
+      Offset(0x7FC),
+      PAFV,  32,         //PEG_AFELNFVMTX2_OFFSET
+      Offset(0x91C),
+      ,       31,
+      BSP1,   1,
+      Offset(0x93C),
+      ,       31,
+      BSP2,   1,
+      Offset(0x95C),
+      ,       31,
+      BSP3,   1,
+      Offset(0x97C),
+      ,       31,
+      BSP4,   1,
+      Offset(0x99C),
+      ,       31,
+      BSP5,   1,
+      Offset(0x9BC),
+      ,       31,
+      BSP6,   1,
+      Offset(0x9DC),
+      ,       31,
+      BSP7,   1,
+      Offset(0x9FC),
+       ,       31,
+      BSP8,   1,
+      Offset(0xC20),
+      ,       4,
+      P1AP,   2,         //AFEOVR.RXSQDETOVR
+      Offset(0xC38),
+      ,       3,
+      P1RM,   1,         //CMNSPARE.PCUNOTL1
+      Offset(0xC3C),
+      ,       31,
+      PRST,   1,
+      Offset(0xC74),
+      P1LT,   4,         //LTSSM_FSM_RESTORE.LTSSM_FSM_PS
+      Offset(0xD0C),
+      LRV1,  32,
+    }
+
+    //
+    // Define a Memory Region for Endpoint on PEG10 root port
+    //
+    OperationRegion (PCS1, SystemMemory, Add(XBAS,ShiftLeft(SBN1,20)), 0xF0)
+    Field(PCS0, DWordAcc, Lock, Preserve)
+    {
+        Offset(0x0),
+        D1VI, 16,
+        Offset(0x2C),
+        S1VI, 16,
+        S1DI, 16,
+    }
+
+    OperationRegion(CAP1, SystemMemory, Add(Add(XBAS,ShiftLeft(SBN1,20)),EEC1),0x14)
+    Field(CAP0,DWordAcc, NoLock,Preserve)
+    {
+        Offset(0x0C),                    // Link Capabilities Register
+        LCP1,   32,                      // Link Capabilities Register Data
+        Offset(0x10),
+        LCT1,   16,                      // Link Control register
+    }
+
+    //
+    // Define a Memory Region for PEG11 root port that will allow access to its
+    // Register Block.
+    //
+    OperationRegion(OPG2, SystemMemory, Add(XBAS,0x9000), 0x1000)
+    Field(OPG2, AnyAcc,NoLock,Preserve)
+    {
+      Offset(0),
+      P2VI,   16,        //Vendor ID PCI offset
+      P2DI,   16,        //Device ID PCI offset
+      Offset(0x06),
+      DSO2,   16,        //Device status PCI offset
+      Offset(0x34),
+      CPO2,   8,         //Capabilities pointer PCI offset
+      Offset(0x0B0),
+      ,       4,
+      P2LD,   1,         //Link Disable
+      Offset(0x11A),
+      ,       1,
+      P2VC,   1,         //VC0RSTS.VC0NP
+      Offset(0x214),
+      ,       16,
+      P2LS,   4,         //PEGSTS.LKS
+      Offset(0x248),
+      ,       7,
+      Q2L2,   1,         //L23_Rdy Entry Request for RTD3
+      Q2L0,   1,         //L23 to Detect Transition for RTD3
+      Offset(0x504),
+      HST2,  32,
+      Offset(0x508),
+      P2TR,   1,         //TRNEN.TREN
+      Offset(0xC20),
+      ,       4,
+      P2AP,   2,         //AFEOVR.RXSQDETOVR
+      Offset(0xC38),
+      ,       3,
+      P2RM,   1,         //CMNSPARE.PCUNOTL1
+      Offset(0xC74),
+      P2LT,   4,         //LTSSM_FSM_RESTORE.LTSSM_FSM_PS
+      Offset(0xD0C),
+      LRV2,  32,
+    }
+
+    //
+    // Define a Memory Region for Endpoint on PEG11 root port
+    //
+    OperationRegion (PCS2, SystemMemory, Add(XBAS,ShiftLeft(SBN2,20)), 0xF0)
+    Field(PCS2, DWordAcc, Lock, Preserve)
+    {
+        Offset(0x0),
+        D2VI, 16,
+        Offset(0x2C),
+        S2VI, 16,
+        S2DI, 16,
+    }
+
+    OperationRegion(CAP2, SystemMemory, Add(Add(XBAS,ShiftLeft(SBN2,20)),EEC2),0x14)
+    Field(CAP2,DWordAcc, NoLock,Preserve)
+    {
+        Offset(0x0C),    // Link Capabilities Register
+        LCP2,   32,      // Link Capabilities Register Data
+        Offset(0x10),
+        LCT2,   16,      // Link Control register
+    }
+
+
+    //
+    // Define a Memory Region for PEG12 root port that will allow access to its
+    // Register Block.
+    //
+    OperationRegion(OPG3, SystemMemory, Add(XBAS,0xA000), 0x1000)
+    Field(OPG3, AnyAcc,NoLock,Preserve)
+    {
+      Offset(0),
+      P3VI,   16,        //Vendor ID PCI offset
+      P3DI,   16,        //Device ID PCI offset
+      Offset(0x06),
+      DSO3,   16,        //Device status PCI offset
+      Offset(0x34),
+      CPO3,   8,         //Capabilities pointer PCI offset
+      Offset(0x0B0),
+      ,       4,
+      P3LD,   1,         //Link Disable
+      Offset(0x11A),
+      ,       1,
+      P3VC,   1,         //VC0RSTS.VC0NP
+      Offset(0x214),
+      ,       16,
+      P3LS,   4,         //PEGSTS.LKS
+      Offset(0x248),
+      ,       7,
+      Q3L2,   1,         //L23_Rdy Entry Request for RTD3
+      Q3L0,   1,         //L23 to Detect Transition for RTD3
+      Offset(0x504),
+      HST3,  32,
+      Offset(0x508),
+      P3TR,   1,         //TRNEN.TREN
+      Offset(0xC20),
+      ,       4,
+      P3AP,   2,         //AFEOVR.RXSQDETOVR
+      Offset(0xC38),
+      ,       3,
+      P3RM,   1,         //CMNSPARE.PCUNOTL1
+      Offset(0xC74),
+      P3LT,   4,         //LTSSM_FSM_RESTORE.LTSSM_FSM_PS
+      Offset(0xD0C),
+      LRV3,  32,
+    }
+
+    //
+    // Define a Memory Region for Endpoint on PEG2 root port
+    //
+    OperationRegion (PCS3, SystemMemory, Add(XBAS,ShiftLeft(SBN3,20)), 0xF0)
+    Field(PCS2, DWordAcc, Lock, Preserve)
+    {
+        Offset(0x0),
+        D3VI, 16,
+        Offset(0x2C),
+        S3VI, 16,
+        S3DI, 16,
+    }
+
+    OperationRegion(CAP3, SystemMemory, Add(Add(XBAS,ShiftLeft(SBN3,20)),EEC3),0x14)
+    Field(CAP3,DWordAcc, NoLock,Preserve)
+    {
+        Offset(0x0C),    // Link Capabilities Register
+        LCP3,   32,      // Link Capabilities Register Data
+        Offset(0x10),
+        LCT3,   16,      // Link Control register
+    }
+
+    //
+    // Name: PGON
+    // Description: Function to put the Pcie Endpoint in ON state
+    // Input: Arg0 -> PEG index
+    // Return: Nothing
+    //
+    Method(PGON,1,Serialized)
+    {
+      Store(Arg0, PION)
+
+      //
+      // Check for the GPIO support on PEG0/1/2/3 Configuration and Return if it is not supported.
+      //
+      If (LEqual(PION, 0))
+      {
+        If (LEqual(SGGP, 0x0))
+        {
+          Return ()
+        }
+      }
+      ElseIf (LEqual(PION, 1))
+      {
+        If (LEqual(P1GP, 0x0))
+        {
+          Return ()
+        }
+      }
+      ElseIf (LEqual(PION, 2))
+      {
+        If (LEqual(P2GP, 0x0))
+        {
+          Return ()
+        }
+      }
+      ElseIf (LEqual(PION, 3))
+      {
+        If (LEqual(P3GP, 0x0))
+        {
+          Return ()
+        }
+      }
+      Store(\XBAS, PEBA)
+      Store(GDEV(PIOF), PDEV)
+      Store(GFUN(PIOF), PFUN)
+
+      /// de-assert CLK_REQ MSK
+      PGSC(Arg0, 1)
+
+      If (LEqual(CCHK(PION, 1), 0))
+      {
+        Return ()
+      }
+
+      //Power on the Endpoint
+      GPPR(PION, 1)
+
+      // Restore PEG Recipe before program L23R2DT
+      //\_SB.PC00.PEG1.RAVR()
+
+      // Enable link for RTD3
+      RTEN()
+
+      // Re-store the DGPU Subsystem VendorID, DeviceID & Link control register data
+      If (LEqual(PION, 0))
+      {
+        Store(H0VI, S0VI)
+        Store(H0DI, S0DI)
+        Or(And(ELC0,0x0043),And(LCT0,0xFFBC),LCT0)
+      }
+      ElseIf (LEqual(PION, 1))
+      {
+        Store(H1VI, S1VI)
+        Store(H1DI, S1DI)
+        Or(And(ELC1,0x0043),And(LCT1,0xFFBC),LCT1)
+      }
+      ElseIf (LEqual(PION, 2))
+      {
+        Store(H2VI, S2VI)
+        Store(H2DI, S2DI)
+        Or(And(ELC2,0x0043),And(LCT2,0xFFBC),LCT2)
+      }
+      ElseIf (LEqual(PION, 3))
+      {
+        Store(H3VI, S3VI)
+        Store(H3DI, S3DI)
+        Or(And(ELC3,0x0043),And(LCT3,0xFFBC),LCT3)
+      }
+      Return ()
+    } // End of Method(PGON,1,Serialized)
+
+    //
+    // Name: PGOF
+    // Description: Function to put the Pcie Endpoint in OFF state
+    // Input: Arg0 -> PEG index
+    // Return: Nothing
+    //
+    Method(PGOF,1,Serialized)
+    {
+
+      Store(Arg0, PIOF)
+      //
+      // Check for the GPIO support on PEG0/1/2 Configuration and Return if it is not supported.
+      //
+      If (LEqual(PIOF, 0))
+      {
+        If (LEqual(SGGP, 0x0))
+        {
+          Return ()
+        }
+      }
+      ElseIf (LEqual(PIOF, 1))
+      {
+        If (LEqual(P1GP, 0x0))
+        {
+          Return ()
+        }
+      }
+      ElseIf (LEqual(PIOF, 2))
+      {
+        If (LEqual(P2GP, 0x0))
+        {
+          Return ()
+        }
+      }
+      ElseIf (LEqual(PIOF, 3))
+      {
+        If (LEqual(P3GP, 0x0))
+        {
+          Return ()
+        }
+      }
+
+      Store(\XBAS, PEBA)
+      Store(GDEV(PIOF), PDEV)
+      Store(GFUN(PIOF), PFUN)
+
+      If (LEqual(CCHK(PIOF, 0), 0))
+      {
+        Return ()
+      }
+
+      // Save Endpoint Link Control register, Subsystem VendorID & Device ID, Link capability Data
+      If (LEqual(Arg0, 0)) //PEG60
+      {
+        Store(LCT0, ELC0)
+        Store(S0VI, H0VI)
+        Store(S0DI, H0DI)
+        Store(LCP0, ECP0)
+      }
+      ElseIf (LEqual(Arg0, 1)) //PEG10
+      {
+        Store(LCT1, ELC1)
+        Store(S1VI, H1VI)
+        Store(S1DI, H1DI)
+        Store(LCP1, ECP1)
+      }
+      ElseIf (LEqual(Arg0, 2)) //PEG11
+      {
+        Store(LCT2, ELC2)
+        Store(S2VI, H2VI)
+        Store(S2DI, H2DI)
+        Store(LCP2, ECP2)
+      }
+      ElseIf (LEqual(Arg0, 3)) //PEG12
+      {
+        Store(LCT3, ELC3)
+        Store(S3VI, H3VI)
+        Store(S3DI, H3DI)
+        Store(LCP3, ECP3)
+      }
+
+      //\_SB.PC00.PEG0.SAVR()
+
+      // Put link in L2
+      RTDS()
+
+      /// assert CLK_REQ MSK
+      ///
+      /// On RTD3 entry, BIOS will instruct the PMC to disable source clocks.
+      /// This is done through sending a PMC IPC command.
+      ///
+      PGSC(Arg0, 0)
+
+      //Power-off the Endpoint
+      GPPR(PIOF, 0)
+      //Method to set Wake GPIO ownership from GPIO to ACPI for Device Initiated RTD3
+      DIWK(PIOF)
+
+      Return ()
+    } // End of Method(PGOF,1,Serialized)
+
+
+    //
+    // Name: GDEV
+    // Description: Function to return the PEG device no for the given PEG index
+    // Input: Arg0 -> PEG index
+    // Return: PEG device no for the given PEG index
+    //
+    Method(GDEV,1)
+    {
+      If(LEqual(Arg0, 0))
+      {
+        Store(0x6, Local0) //Device6-Function0 = 00110.000
+      }
+      ElseIf(LEqual(Arg0, 1))
+      {
+        Store(0x1, Local0) //Device1-Function0 = 00001.000
+      }
+      ElseIf(LEqual(Arg0, 2))
+      {
+        Store(0x1, Local0) //Device1-Function2 = 00001.001
+      }
+      ElseIf(LEqual(Arg0, 3))
+      {
+        Store(0x1, Local0) //Device1-Function3 = 00001.010
+      }
+
+      Return(Local0)
+    } // End of Method(GDEV,1)
+
+    //
+    // Name: GFUN
+    // Description: Function to return the PEG function no for the given PEG index
+    // Input: Arg0 -> PEG index
+    // Return: PEG function no for the given PEG index
+    //
+    Method(GFUN,1)
+    {
+      If(LEqual(Arg0, 0))
+      {
+        Store(0x0, Local0) //Device6-Function0 = 00110.000
+      }
+      ElseIf(LEqual(Arg0, 1))
+      {
+        Store(0x0, Local0) //Device1-Function0 = 00001.000
+      }
+      ElseIf(LEqual(Arg0, 2))
+      {
+        Store(0x1, Local0) //Device1-Function1 = 00001.001
+      }
+      ElseIf(LEqual(Arg0, 2))
+      {
+        Store(0x2, Local0) //Device1-Function2 = 00001.010
+      }
+
+      Return(Local0)
+    } // End of Method(GFUN,1)
+
+    //
+    // Name: CCHK
+    // Description: Function to check whether _ON/_OFF sequence is allowed to execute for the given PEG controller or not
+    // Input: Arg0 -> PEG index
+    //        Arg1 -> 0 means _OFF sequence, 1 means _ON sequence
+    // Return: 0 - Don't execute the flow, 1 - Execute the flow
+    //
+    Method(CCHK,2)
+    {
+
+      //Check for Referenced PEG controller is present or not
+      If(LEqual(Arg0, 0))
+      {
+        Store(P0VI, Local7)
+      }
+      ElseIf(LEqual(Arg0, 1))
+      {
+        Store(P1VI, Local7)
+      }
+      ElseIf(LEqual(Arg0, 2))
+      {
+        Store(P2VI, Local7)
+      }
+      ElseIf(LEqual(Arg0, 3))
+      {
+        Store(P3VI, Local7)
+      }
+
+      If(LEqual(Local7, IVID))
+      {
+        Return(0)
+      }
+
+      If(LNotEqual(Arg0, 1))
+      {
+        //Check for PEG10 controller presence
+        Store(P1VI, Local7)
+        If(LEqual(Local7, IVID))
+        {
+          Return(0)
+        }
+      }
+
+      //If Endpoint is not present[already disabled] before executing PGOF then don't call the PGOF method
+      //If Endpoint is present[already enabled] before executing PGON then don't call the PGON method
+      If(LEqual(Arg1, 0))
+      {
+        //_OFF sequence condition check
+        If(LEqual(Arg0, 0))
+        {
+          If(LEqual(SGPI(SGGP, PWE0, PWG0, PWA0), 0))
+          {
+            Return(0)
+          }
+        }
+        If(LEqual(Arg0, 1))
+        {
+          If(LEqual(SGPI(P1GP, PWE1, PWG1, PWA1), 0))
+          {
+            Return(0)
+          }
+        }
+        If(LEqual(Arg0, 2))
+        {
+          If(LEqual(SGPI(P2GP, PWE2, PWG2, PWA2), 0))
+          {
+            Return(0)
+          }
+        }
+        If(LEqual(Arg0, 3))
+        {
+          If(LEqual(SGPI(P3GP, PWE3, PWG3, PWA3), 0))
+          {
+            Return(0)
+          }
+        }
+      }
+      ElseIf(LEqual(Arg1, 1))
+      {
+        //_ON sequence condition check
+        If(LEqual(Arg0, 0))
+        {
+          If(LEqual(SGPI(SGGP, PWE0, PWG0, PWA0), 1))
+          {
+            Return(0)
+          }
+        }
+        If(LEqual(Arg0, 1))
+        {
+          If(LEqual(SGPI(P1GP, PWE1, PWG1, PWA1), 1))
+          {
+            Return(0)
+          }
+        }
+        If(LEqual(Arg0, 2))
+        {
+          If(LEqual(SGPI(P2GP, PWE2, PWG2, PWA2), 1))
+          {
+            Return(0)
+          }
+        }
+        If(LEqual(Arg0, 3))
+        {
+          If(LEqual(SGPI(P3GP, PWE3, PWG3, PWA3), 1))
+          {
+            Return(0)
+          }
+        }
+      }
+
+      Return(1)
+    }
+
+
+    //
+    // Name: SGPI [PCIe GPIO Read]
+    // Description: Function to Read from PCIe GPIO
+    // Input: Arg0 -> Gpio Support
+    //        Arg1 -> Expander Number
+    //        Arg2 -> Gpio Number
+    //        Arg3 -> Active Information
+    // Return: GPIO value
+    //
+    Method(SGPI, 4, Serialized)
+    {
+      If (LEqual(Arg0, 0x01))
+      {
+        //
+        // PCH based GPIO
+        //
+        If (CondRefOf(\_SB.GGOV))
+        {
+          Store(\_SB.GGOV(Arg2), Local0)
+        }
+      }
+      //
+      // Invert if Active Low
+      //
+      If (LEqual(Arg3,0))
+      {
+        Not(Local0, Local0)
+        And (Local0, 0x01, Local0)
+      }
+
+      Return(Local0)
+    }// End of Method(SGPI)
+
+    // Name: PGSC [PEG port source clock control]
+    // Description: Function to enable/disable PEG port source clocks
+    // Input: Arg0 -> PEG index
+    //        Arg1 -> Enable/Disable Clock (0 = Disable, 1 = Enable)
+    // Return: Nothing
+    //
+
+    Method(PGSC, 2, Serialized)
+    {
+      If(LEqual(Arg0, 0)) { // PEG0
+        Store (P0SC, Local0)
+      } ElseIf(LEqual(Arg0, 1)) { // PEG1
+        Store (P1SC, Local0)
+      } ElseIf(LEqual(Arg0, 2)) { // PEG2
+        Store (P2SC, Local0)
+      } ElseIf(LEqual(Arg0, 3)) {// PEG3
+        Store (P3SC, Local0)
+      } Else {
+        Return()
+      }
+
+      SPCO (Local0, Arg1)
+    }// End of Method(PGSC)
+
+    //
+    // Name: GPPR
+    // Description: Function to do Endpoint ON/OFF using GPIOs
+    //              There are two GPIOs currently used to control Third Party Vendor[TPV] DGPU Endpoint devices:
+    //              (1) DGPU_PWR_EN [used for Power control]
+    //              (2) DGPU_HOLD_RST[used for Reset control]
+    // Input: Arg0 -> PEG index
+    //        Arg1 -> 0 means _OFF sequence, 1 means _ON sequence
+    // Return: Nothing
+    //
+    Method(GPPR,2)
+    {
+
+      If(LEqual(Arg1, 0))
+      {
+        //_OFF sequence GPIO programming
+        If(LEqual(Arg0, 0))
+        {
+          SGPO(SGGP, HRE0, HRG0, HRA0, 1) // Assert PCIe0/dGPU_HOLD_RST# (PERST#)
+          //Sleep(DLHR)                     // As per the PCIe spec, Wait for 'given'ms after Assert the Reset
+          SGPO(SGGP, PWE0, PWG0, PWA0, 0) // Deassert PCIe0/dGPU_PWR_EN#
+        }
+
+        If(LEqual(Arg0, 1))
+        {
+          SGPO(P1GP, HRE1, HRG1, HRA1, 1) // Assert PCIe1_HOLD_RST# (PERST#)
+          //Sleep(DLHR)                     // As per the PCIe spec, Wait for 'given'ms after Assert the Reset
+          SGPO(P1GP, PWE1, PWG1, PWA1, 0) // Deassert PCIe1_PWR_EN#
+        }
+
+        If(LEqual(Arg0, 2))
+        {
+          SGPO(P2GP, HRE2, HRG2, HRA2, 1) // Assert PCIe2_HOLD_RST# (PERST#)
+          //Sleep(DLHR)                     // As per the PCIe spec, Wait for 'given'ms after Assert the Reset
+          SGPO(P2GP, PWE2, PWG2, PWA2, 0) // Deassert PCIe2_PWR_EN#
+        }
+
+        If(LEqual(Arg0, 3))
+        {
+          SGPO(P3GP, HRE3, HRG3, HRA3, 1) // Assert PCIe3_HOLD_RST# (PERST#)
+          //Sleep(DLHR)                     // As per the PCIe spec, Wait for 'given'ms after Assert the Reset
+          SGPO(P3GP, PWE3, PWG3, PWA3, 0) // Deassert PCIe2_PWR_EN#
+        }
+      }
+      ElseIf(LEqual(Arg1, 1))
+      {
+        //_ON sequence GPIO programming
+        If(LEqual(Arg0, 0))
+        {
+          SGPO(SGGP, PWE0, PWG0, PWA0, 1) //Assert dGPU_PWR_EN#
+
+          //Sleep(DLPW) // Wait for 'given'ms for power to get stable
+          SGPO(SGGP, HRE0, HRG0, HRA0, 0) //Deassert dGPU_HOLD_RST# as per the PCIe spec
+
+          //Sleep(DLHR) // Wait for 'given'ms after Deassert
+        }
+
+        If(LEqual(Arg0, 1))
+        {
+          SGPO(P1GP, PWE1, PWG1, PWA1, 1) //Assert dGPU_PWR_EN#
+
+          //Sleep(DLPW) // Wait for 'given'ms for power to get stable
+          SGPO(P1GP, HRE1, HRG1, HRA1, 0) //Deassert dGPU_HOLD_RST# as per the PCIe spec
+
+          //Sleep(DLHR) // Wait for 'given'ms after Deassert
+        }
+
+        If(LEqual(Arg0, 2))
+        {
+          SGPO(P2GP, PWE2, PWG2, PWA2, 1) //Assert dGPU_PWR_EN#
+
+          //Sleep(DLPW) // Wait for 'given'ms for power to get stable
+          SGPO(P2GP, HRE2, HRG2, HRA2, 0) //Deassert dGPU_HOLD_RST# as per the PCIe spec
+
+          //Sleep(DLHR) // Wait for 'given'ms after Deassert
+        }
+
+        If(LEqual(Arg0, 3))
+        {
+          SGPO(P3GP, PWE3, PWG3, PWA3, 1) //Assert dGPU_PWR_EN#
+
+          //Sleep(DLPW) // Wait for 'given'ms for power to get stable
+          SGPO(P3GP, HRE3, HRG3, HRA3, 0) //Deassert dGPU_HOLD_RST# as per the PCIe spec
+
+          //Sleep(DLHR) // Wait for 'given'ms after Deassert
+        }
+      }
+    } // End of Method(GPPR,2)
+
+    //
+    // Name: SGPO [PCIe GPIO Write]
+    // Description: Function to write into PCIe GPIO
+    // Input: Arg0 -> Gpio Support
+    //        Arg1 -> Expander Number
+    //        Arg2 -> Gpio Number
+    //        Arg3 -> Active Information
+    //        Arg4 -> Value to write
+    // Return: Nothing
+    //
+
+    Method(SGPO, 5, Serialized)
+    {
+      //
+      // Invert if Active Low
+      //
+      If (LEqual(Arg3,0))
+      {
+        Not(Arg4, Arg4)
+        And(Arg4, 0x01, Arg4)
+      }
+      If (LEqual(Arg0, 0x01))
+      {
+        //
+        // PCH based GPIO
+        //
+        If (CondRefOf(\_SB.SGOV))
+        {
+          \_SB.SGOV(Arg2, Arg4)
+        }
+      }
+    } // End of Method(SGPO)
+
+    //
+    // Name: DIWK
+    // Description: Function which set the GPIO ownership to ACPI for device initiated RTD3
+    // Input: PEG Index
+    // Return: Nothing
+    //
+    Method(DIWK,1)
+    {
+      If (LEqual(Arg0, 0))
+      {
+        \_SB.PC00.PEG0.P0EW()
+      }
+      ElseIf (LEqual(Arg0, 1))
+      {
+        \_SB.PC00.PEG1.P1EW()
+      }
+      ElseIf (LEqual(Arg0, 2))
+      {
+        \_SB.PC00.PEG2.P2EW()
+      }
+      ElseIf (LEqual(Arg0, 3))
+      {
+        \_SB.PC00.PEG3.P3EW()
+      }
+    }
+  }// End of Scope (\_SB.PC00)
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/PegRtd3.asl b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/PegRtd3.asl
new file mode 100644
index 0000000000..b5d1a4e35e
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/PegRtd3.asl
@@ -0,0 +1,124 @@
+/** @file
+  This file contains the device definitions of the SystemAgent
+  PCIE ACPI Reference Code.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+Scope (\_SB.PC00) {
+
+  OperationRegion(PXCS,PCI_Config,0x00,0x480)
+  Field(PXCS,AnyAcc, NoLock, Preserve)
+  {
+    Offset(0),
+    VDID, 32,
+    Offset(0x50), // LCTL - Link Control Register
+    L0SE, 1,      // 0, L0s Entry Enabled
+    , 3,
+    LDIS, 1,
+    , 3,
+    Offset(0x52), // LSTS - Link Status Register
+    , 13,
+    LASX, 1,      // 0, Link Active Status
+    Offset(0x5A), // SLSTS[7:0] - Slot Status Register
+    ABPX, 1,      // 0, Attention Button Pressed
+    , 2,
+    PDCX, 1,      // 3, Presence Detect Changed
+    , 2,
+    PDSX, 1,      // 6, Presence Detect State
+    , 1,
+    Offset(0x60), // RSTS - Root Status Register
+    , 16,
+    PSPX, 1,      // 16,  PME Status
+    Offset(0xA4),
+    D3HT, 2,      // Power State
+    Offset(0xD8), // 0xD8, MPC - Miscellaneous Port Configuration Register
+    , 30,
+    HPEX, 1,      // 30,  Hot Plug SCI Enable
+    PMEX, 1,      // 31,  Power Management SCI Enable
+    Offset(0xE0), // 0xE0, SPR - Scratch Pad Register
+    , 0,
+    SCB0, 1,      // Sticky Scratch Pad Bit SCB0
+    Offset(0xE2), // 0xE2, RPPGEN - Root Port Power Gating Enable
+    , 2,
+    L23E, 1,       // 2,   L23_Rdy Entry Request (L23ER)
+    L23R, 1,       // 3,   L23_Rdy to Detect Transition (L23R2DT)
+    Offset(0x324), // 0x324 - PCIEDBG
+    , 3,
+    LEDM, 1,       // PCIEDBG.DMIL1EDM
+    Offset(0x328), // 0x328 - PCIESTS1
+    , 24,
+    LTSM, 8,
+  }
+  Field(PXCS,AnyAcc, NoLock, WriteAsZeros)
+  {
+    Offset(0xDC), // 0xDC, SMSCS - SMI/SCI Status Register
+    , 30,
+    HPSX, 1,      // 30,  Hot Plug SCI Status
+    PMSX, 1       // 31,  Power Management SCI Status
+  }
+
+    //
+    // Name: RTEN
+    // Description: Function to Enable the link for RTD3 [RCTL.L22DT]
+    // Input: PEG Index
+    // Return: Nothing
+    //
+    Method(RTEN, 0, Serialized)
+    {
+      If (LNotEqual (SCB0,0x1)) {
+        Return ()
+      }
+
+      /// Set L23_Rdy to Detect Transition  (L23R2DT)
+      Store(1, L23R)
+      Store(0, Local0)
+      /// Wait for transition to Detect
+      While(L23R) {
+        If(Lgreater(Local0, 4))
+        {
+          Break
+        }
+        Sleep(16)
+        Increment(Local0)
+      }
+      Store(0,SCB0)
+
+      /// Once in Detect, wait up to 124 ms for Link Active (typically happens in under 70ms)
+      /// Worst case per PCIe spec from Detect to Link Active is:
+      /// 24ms in Detect (12+12), 72ms in Polling (24+48), 28ms in Config (24+2+2+2+2)
+      Store(0, Local0)
+      While(LEqual(LASX,0)) {
+        If(Lgreater(Local0, 8))
+        {
+          Break
+        }
+        Sleep(16)
+        Increment(Local0)
+      }
+    }
+
+    //
+    // Name: RTDS
+    // Description: Function to Disable link for RTD3 [RCTL.L23ER]
+    // Input: PEG Index
+    // Return: Nothing
+    //
+    Method(RTDS, 0, Serialized)
+    {
+      Store(1, L23E)
+      Sleep(16)
+      Store(0, Local0)
+      While(L23E) {
+        If(Lgreater(Local0, 4))
+        {
+          Break
+        }
+        Sleep(16)
+        Increment(Local0)
+      }
+      Store(1,SCB0)
+    }
+
+} // End of Scope (\_SB.PC00)
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Sa.asl b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Sa.asl
new file mode 100644
index 0000000000..5228d9d753
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Sa.asl
@@ -0,0 +1,26 @@
+/** @file
+  This file contains the device definition of the System Agent
+  ACPI reference code.
+  Currently defines the device objects for the
+  System Agent PCI Express* ports (PEG), iGfx and other devices.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+External(\HGMD)
+External(\HGST)
+External(\_SB.PC00, DeviceObj)
+External(\_SB.PC00.GFX0, DeviceObj)
+External(\_SB.PC00.IPU0, DeviceObj)
+External(\_SB.PC00.B0D3, DeviceObj)
+External(\_SB.PC00.PCIC, MethodObj)
+External(\_SB.PC00.PCID, MethodObj)
+///
+/// CPU PCIe Root Port
+///
+include("CpuPcieRp.asl")
+include("PegCommon.asl")
+If(LAnd((LEqual(HGMD,2)), (LEqual(HGST,1)))) {
+  include("PegRtd3.asl")
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.asl b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.asl
new file mode 100644
index 0000000000..0494c659e0
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.asl
@@ -0,0 +1,20 @@
+/** @file
+  This file contains the SystemAgent SSDT Table ASL code.
+  It defines a Global NVS table which exchanges datas between OS
+  and BIOS.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+DefinitionBlock (
+  "SaSsdt.aml",
+  "SSDT",
+  0x02,
+  "SaSsdt",
+  "SaSsdt ",
+  0x3000
+  )
+{
+  Include ("Sa.asl")
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.inf b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.inf
new file mode 100644
index 0000000000..d0d1494b99
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.inf
@@ -0,0 +1,22 @@
+## @file
+#  Component description file for the ACPI tables
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION          = 0x00010005
+BASE_NAME            = SaSsdt
+FILE_GUID            = ca89914d-2317-452e-b245-36c6fb77a9c6
+MODULE_TYPE          = USER_DEFINED
+VERSION_STRING       = 1.0
+
+[Sources]
+  SaSsdt.asl
+
+
+[Packages]
+  MdePkg/MdePkg.dec
+  TigerlakeSiliconPkg/SiPkg.dec
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLib.c b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLib.c
new file mode 100644
index 0000000000..d33c20605a
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLib.c
@@ -0,0 +1,264 @@
+/** @file
+  This file provide services for DXE phase policy default initialization
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "DxeSaPolicyLibrary.h"
+#include <Library/DxeGraphicsPolicyLib.h>
+#include <Library/DxeVtdPolicyLib.h>
+#include <Register/SaRegsHostBridge.h>
+
+extern EFI_GUID gMemoryDxeConfigGuid;
+extern EFI_GUID gPcieDxeConfigGuid;
+
+/**
+  This function prints the SA DXE phase policy.
+
+  @param[in] SaPolicy - SA DXE Policy protocol
+**/
+VOID
+SaPrintPolicyProtocol (
+  IN  SA_POLICY_PROTOCOL      *SaPolicy
+  )
+{
+  EFI_STATUS                  Status;
+  PCIE_DXE_CONFIG             *PcieDxeConfig;
+  MEMORY_DXE_CONFIG           *MemoryDxeConfig;
+
+  //
+  // Get requisite IP Config Blocks which needs to be used here
+  //
+  Status = GetConfigBlock ((VOID *) SaPolicy, &gPcieDxeConfigGuid, (VOID *)&PcieDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  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"));
+  //@todo: Matching the hardcode at lines 384.  Need to be addressed.
+  DEBUG ((DEBUG_INFO, " SpdAddressTable[%d] :", 4));
+  for (i = 0; i < 4; i++) {
+    DEBUG ((DEBUG_INFO, " %x", MemoryDxeConfig->SpdAddressTable[i]));
+  }
+  DEBUG ((DEBUG_INFO, "\n"));
+
+  DEBUG ((DEBUG_INFO, " ChannelASlotMap : %x\n", MemoryDxeConfig->ChannelASlotMap));
+  DEBUG ((DEBUG_INFO, " ChannelBSlotMap : %x\n", MemoryDxeConfig->ChannelBSlotMap));
+  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));
+  for (i = 0; i < SA_PEG_MAX_FUN; i++) {
+    DEBUG ((DEBUG_INFO, " %x", PcieDxeConfig->PegAspm[i]));
+  }
+  DEBUG ((DEBUG_INFO, "\n"));
+
+  DEBUG ((DEBUG_INFO, " PegRootPortHPE[%d] :", SA_PEG_MAX_FUN));
+  for (i = 0; i < SA_PEG_MAX_FUN; i++) {
+    DEBUG ((DEBUG_INFO, " %x", PcieDxeConfig->PegRootPortHPE[i]));
+  }
+  DEBUG ((DEBUG_INFO, "\n"));
+
+
+  DEBUG ((DEBUG_INFO, "\n------------------------ SA Policy (DXE) print END -----------------\n"));
+  DEBUG_CODE_END ();
+
+  return;
+}
+
+/**
+  Load DXE Config block default for PCIe
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadPcieDxeDefault (
+  IN VOID    *ConfigBlockPointer
+  )
+{
+  UINT8                  Index;
+  PCIE_DXE_CONFIG        *PcieDxeConfig;
+
+  PcieDxeConfig = ConfigBlockPointer;
+  DEBUG ((DEBUG_INFO, "PcieDxeConfig->Header.GuidHob.Name = %g\n", &PcieDxeConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "PcieDxeConfig->Header.GuidHob.Header.HobLength = 0x%x\n", PcieDxeConfig->Header.GuidHob.Header.HobLength));
+  ///
+  /// Initialize the PCIE Configuration
+  /// PEG ASPM per port configuration. 4 PEG controllers i.e. 0,1,2,3
+  ///
+  for (Index = 0; Index < SA_PEG_MAX_FUN; Index++) {
+    PcieDxeConfig->PegAspm[Index]       = CpuPcieAspmAutoConfig;
+  }
+
+  for (Index = 0; Index < SA_PEG_MAX_FUN; Index++) {
+    PcieDxeConfig->PegPwrOpt[Index].LtrEnable            = 1;
+    PcieDxeConfig->PegPwrOpt[Index].LtrMaxSnoopLatency   = V_SA_LTR_MAX_SNOOP_LATENCY_VALUE;
+    PcieDxeConfig->PegPwrOpt[Index].LtrMaxNoSnoopLatency = V_SA_LTR_MAX_NON_SNOOP_LATENCY_VALUE;
+    PcieDxeConfig->PegPwrOpt[Index].ObffEnable           = 1;
+  }
+}
+
+
+/**
+  Load DXE Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadMemoryDxeDefault (
+  IN VOID    *ConfigBlockPointer
+  )
+{
+  MEMORY_DXE_CONFIG        *MemoryDxeConfig;
+
+  MemoryDxeConfig = ConfigBlockPointer;
+  DEBUG ((DEBUG_INFO, "MemoryDxeConfig->Header.GuidHob.Name = %g\n", &MemoryDxeConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "MemoryDxeConfig->Header.GuidHob.Header.HobLength = 0x%x\n", MemoryDxeConfig->Header.GuidHob.Header.HobLength));
+  ///
+  /// 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->ChannelASlotMap = 0x01;
+  MemoryDxeConfig->ChannelBSlotMap = 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 [] = {
+  {&gPcieDxeConfigGuid,     sizeof (PCIE_DXE_CONFIG),     PCIE_DXE_CONFIG_REVISION,      LoadPcieDxeDefault},
+  {&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 += VtdGetConfigBlockTotalSizeDxe ();
+  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);
+
+  // Vtd
+  Status = VtdAddConfigBlocksDxe((VOID *) SaInitPolicy);
+  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);
+  VtdPrintPolicyDxe (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/TigerlakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLib.inf
new file mode 100644
index 0000000000..8af3d09b80
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLib.inf
@@ -0,0 +1,48 @@
+## @file
+# Component description file for the PeiSaPolicy library.
+#
+#  Copyright (c) 2021, 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
+DxeVtdPolicyLib
+
+[Packages]
+MdePkg/MdePkg.dec
+TigerlakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+DxeSaPolicyLib.c
+DxeSaPolicyLibrary.h
+
+
+[Guids]
+gPcieDxeConfigGuid
+gMemoryDxeConfigGuid
+
+
+[Protocols]
+gSaPolicyProtocolGuid ## PRODUCES
+
+[Pcd]
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLibrary.h b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLibrary.h
new file mode 100644
index 0000000000..d46dd44df3
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLibrary.h
@@ -0,0 +1,34 @@
+/** @file
+  Header file for the DxeSaPolicy library.
+
+  Copyright (c) 2021, 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
+#define MAX_PCIE_ASPM_OVERRIDE  500
+#define MAX_PCIE_LTR_OVERRIDE   500
+///
+/// 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
+#define DIMM_SMB_SPD_P0C0D2 0xA8
+#define DIMM_SMB_SPD_P0C1D2 0xAA
+
+#endif // _DXE_SA_POLICY_LIBRARY_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/PeiDxeSmmSaPlatformLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/PeiDxeSmmSaPlatformLib.inf
new file mode 100644
index 0000000000..0a632fc81a
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/PeiDxeSmmSaPlatformLib.inf
@@ -0,0 +1,32 @@
+## @file
+# Component description file for SA Platform Lib
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiDxeSmmSaPlatformLib
+FILE_GUID = 9DB5ACB4-DB23-43AE-A283-2ABEF365CBE0
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = SaPlatformLib
+
+
+[LibraryClasses]
+BaseLib
+BaseMemoryLib
+DebugLib
+IoLib
+
+[Packages]
+MdePkg/MdePkg.dec
+TigerlakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+SaPlatformLibrary.h
+SaPlatformLibrary.c
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/SaPlatformLibrary.c b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/SaPlatformLibrary.c
new file mode 100644
index 0000000000..42902d795c
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/SaPlatformLibrary.c
@@ -0,0 +1,68 @@
+/** @file
+  SA Platform Lib implementation.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include "SaPlatformLibrary.h"
+#include <Library/PciSegmentLib.h>
+#include <IndustryStandard/Pci22.h>
+#include <CpuPcieInfo.h>
+
+
+/**
+  Checks if SKU is Mobile
+
+  @retval FALSE  SKU is not Mobile
+  @retval TRUE   SKU is Mobile
+**/
+BOOLEAN
+EFIAPI
+IsMobileSku (
+  VOID
+  )
+{
+  UINT16           DeviceId;
+
+  DeviceId = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, SA_MC_DEV, SA_MC_FUN, R_SA_MC_DEVICE_ID));
+  if (
+      (DeviceId == V_SA_DEVICE_ID_MB_ULT_1) || \
+      (DeviceId == V_SA_DEVICE_ID_MB_ULT_2) || \
+      (DeviceId == V_SA_DEVICE_ID_MB_ULX_1) || \
+      (DeviceId == V_SA_DEVICE_ID_MB_ULX_2) \
+    ) {
+    return TRUE;
+  }
+  return FALSE;
+}
+
+/**
+  Checks if SKU is Desktop
+
+  @retval FALSE  SKU is not Desktop
+  @retval TRUE   SKU is Desktop
+**/
+BOOLEAN
+EFIAPI
+IsDesktopSku (
+  VOID
+  )
+{
+  return FALSE;
+}
+
+/**
+  Checks if SKU is Server
+
+  @retval FALSE  SKU is not Server
+  @retval TRUE   SKU is Server
+**/
+BOOLEAN
+EFIAPI
+IsServerSku (
+  VOID
+  )
+{
+  return FALSE;
+}
+
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/SaPlatformLibrary.h b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/SaPlatformLibrary.h
new file mode 100644
index 0000000000..10513d0ea0
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/SaPlatformLibrary.h
@@ -0,0 +1,21 @@
+/** @file
+  Header file for SA Platform Lib implementation.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SA_PLATFORM_LIBRARY_IMPLEMENTATION_H_
+#define _SA_PLATFORM_LIBRARY_IMPLEMENTATION_H_
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Register/SaRegsHostBridge.h>
+#include <CpuAccess.h>
+#include <Library/SaPlatformLib.h>
+#include <Register/IgdRegs.h>
+
+#endif
-- 
2.24.0.windows.2



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#70984): https://edk2.groups.io/g/devel/message/70984
Mute This Topic: https://groups.io/mt/80274151/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